blob: fba3bf0371429a7c2539420e1f4b0e4059200870 [file] [log] [blame]
Paul Yang57b65972019-03-19 22:27:13 -07001/* Amalgamated source file */
2#define _XOPEN_SOURCE 700
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003#include "upb.h"
Paul Yang9bda1f12018-09-22 18:57:43 -07004
5#if UINTPTR_MAX == 0xffffffff
6#define UPB_SIZE(size32, size64) size32
7#else
8#define UPB_SIZE(size32, size64) size64
9#endif
10
11#define UPB_FIELD_AT(msg, fieldtype, offset) \
12 *(fieldtype*)((const char*)(msg) + offset)
13
14#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
15 UPB_FIELD_AT(msg, int, case_offset) == case_val \
16 ? UPB_FIELD_AT(msg, fieldtype, offset) \
17 : default
18
19#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
20 UPB_FIELD_AT(msg, int, case_offset) = case_val; \
21 UPB_FIELD_AT(msg, fieldtype, offset) = value;
Paul Yang6dd563a2018-03-08 17:35:22 -080022/* This file was generated by upbc (the upb compiler) from the input
23 * file:
24 *
25 * google/protobuf/descriptor.proto
26 *
27 * Do not edit -- your changes will be discarded when the file is
28 * regenerated. */
29
30#include <stddef.h>
31
32
Paul Yang9bda1f12018-09-22 18:57:43 -070033static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -080034 &google_protobuf_FileDescriptorProto_msginit,
35};
36
Paul Yang9bda1f12018-09-22 18:57:43 -070037static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
38 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -080039};
40
Paul Yang9bda1f12018-09-22 18:57:43 -070041const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -080042 &google_protobuf_FileDescriptorSet_submsgs[0],
43 &google_protobuf_FileDescriptorSet__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -070044 UPB_SIZE(4, 8), 1, false,
Paul Yang6dd563a2018-03-08 17:35:22 -080045};
46
Paul Yang9bda1f12018-09-22 18:57:43 -070047static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
Paul Yang6dd563a2018-03-08 17:35:22 -080048 &google_protobuf_DescriptorProto_msginit,
49 &google_protobuf_EnumDescriptorProto_msginit,
50 &google_protobuf_FieldDescriptorProto_msginit,
51 &google_protobuf_FileOptions_msginit,
52 &google_protobuf_ServiceDescriptorProto_msginit,
53 &google_protobuf_SourceCodeInfo_msginit,
54};
55
Paul Yang9bda1f12018-09-22 18:57:43 -070056static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
Paul Yang57b65972019-03-19 22:27:13 -070057 {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
58 {2, UPB_SIZE(12, 24), 2, 0, 9, 1},
59 {3, UPB_SIZE(36, 72), 0, 0, 9, 3},
60 {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
61 {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
62 {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
63 {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
64 {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
65 {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
66 {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
67 {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
68 {12, UPB_SIZE(20, 40), 3, 0, 9, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -080069};
70
Paul Yang9bda1f12018-09-22 18:57:43 -070071const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -080072 &google_protobuf_FileDescriptorProto_submsgs[0],
73 &google_protobuf_FileDescriptorProto__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -070074 UPB_SIZE(64, 128), 12, false,
Paul Yang6dd563a2018-03-08 17:35:22 -080075};
76
Paul Yang9bda1f12018-09-22 18:57:43 -070077static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
Paul Yang6dd563a2018-03-08 17:35:22 -080078 &google_protobuf_DescriptorProto_msginit,
79 &google_protobuf_DescriptorProto_ExtensionRange_msginit,
80 &google_protobuf_DescriptorProto_ReservedRange_msginit,
81 &google_protobuf_EnumDescriptorProto_msginit,
82 &google_protobuf_FieldDescriptorProto_msginit,
83 &google_protobuf_MessageOptions_msginit,
84 &google_protobuf_OneofDescriptorProto_msginit,
85};
86
Paul Yang9bda1f12018-09-22 18:57:43 -070087static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
Paul Yang57b65972019-03-19 22:27:13 -070088 {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
89 {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
90 {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
91 {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
92 {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
93 {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
94 {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
95 {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
96 {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
97 {10, UPB_SIZE(44, 88), 0, 0, 9, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -080098};
99
Paul Yang9bda1f12018-09-22 18:57:43 -0700100const upb_msglayout google_protobuf_DescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800101 &google_protobuf_DescriptorProto_submsgs[0],
102 &google_protobuf_DescriptorProto__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700103 UPB_SIZE(48, 96), 10, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800104};
105
Paul Yang9bda1f12018-09-22 18:57:43 -0700106static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800107 &google_protobuf_ExtensionRangeOptions_msginit,
108};
109
Paul Yang9bda1f12018-09-22 18:57:43 -0700110static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
111 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
112 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
113 {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800114};
115
Paul Yang9bda1f12018-09-22 18:57:43 -0700116const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800117 &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
118 &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700119 UPB_SIZE(16, 24), 3, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800120};
121
Paul Yang9bda1f12018-09-22 18:57:43 -0700122static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
123 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
124 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800125};
126
Paul Yang9bda1f12018-09-22 18:57:43 -0700127const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800128 NULL,
129 &google_protobuf_DescriptorProto_ReservedRange__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700130 UPB_SIZE(12, 12), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800131};
132
Paul Yang9bda1f12018-09-22 18:57:43 -0700133static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800134 &google_protobuf_UninterpretedOption_msginit,
135};
136
Paul Yang9bda1f12018-09-22 18:57:43 -0700137static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
138 {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800139};
140
Paul Yang9bda1f12018-09-22 18:57:43 -0700141const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800142 &google_protobuf_ExtensionRangeOptions_submsgs[0],
143 &google_protobuf_ExtensionRangeOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700144 UPB_SIZE(4, 8), 1, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800145};
146
Paul Yang9bda1f12018-09-22 18:57:43 -0700147static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800148 &google_protobuf_FieldOptions_msginit,
149};
150
Paul Yang9bda1f12018-09-22 18:57:43 -0700151static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = {
152 {1, UPB_SIZE(32, 32), 5, 0, 9, 1},
153 {2, UPB_SIZE(40, 48), 6, 0, 9, 1},
154 {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
155 {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
156 {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
157 {6, UPB_SIZE(48, 64), 7, 0, 9, 1},
158 {7, UPB_SIZE(56, 80), 8, 0, 9, 1},
159 {8, UPB_SIZE(72, 112), 10, 0, 11, 1},
160 {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
161 {10, UPB_SIZE(64, 96), 9, 0, 9, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800162};
163
Paul Yang9bda1f12018-09-22 18:57:43 -0700164const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800165 &google_protobuf_FieldDescriptorProto_submsgs[0],
166 &google_protobuf_FieldDescriptorProto__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700167 UPB_SIZE(80, 128), 10, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800168};
169
Paul Yang9bda1f12018-09-22 18:57:43 -0700170static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800171 &google_protobuf_OneofOptions_msginit,
172};
173
Paul Yang9bda1f12018-09-22 18:57:43 -0700174static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
Paul Yang57b65972019-03-19 22:27:13 -0700175 {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
176 {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800177};
178
Paul Yang9bda1f12018-09-22 18:57:43 -0700179const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800180 &google_protobuf_OneofDescriptorProto_submsgs[0],
181 &google_protobuf_OneofDescriptorProto__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700182 UPB_SIZE(16, 32), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800183};
184
Paul Yang9bda1f12018-09-22 18:57:43 -0700185static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800186 &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
187 &google_protobuf_EnumOptions_msginit,
188 &google_protobuf_EnumValueDescriptorProto_msginit,
189};
190
Paul Yang9bda1f12018-09-22 18:57:43 -0700191static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
Paul Yang57b65972019-03-19 22:27:13 -0700192 {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
193 {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
194 {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
195 {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
196 {5, UPB_SIZE(24, 48), 0, 0, 9, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800197};
198
Paul Yang9bda1f12018-09-22 18:57:43 -0700199const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800200 &google_protobuf_EnumDescriptorProto_submsgs[0],
201 &google_protobuf_EnumDescriptorProto__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700202 UPB_SIZE(32, 64), 5, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800203};
204
Paul Yang9bda1f12018-09-22 18:57:43 -0700205static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
206 {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
207 {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800208};
209
Paul Yang9bda1f12018-09-22 18:57:43 -0700210const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800211 NULL,
212 &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700213 UPB_SIZE(12, 12), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800214};
215
Paul Yang9bda1f12018-09-22 18:57:43 -0700216static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800217 &google_protobuf_EnumValueOptions_msginit,
218};
219
Paul Yang9bda1f12018-09-22 18:57:43 -0700220static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
Paul Yang57b65972019-03-19 22:27:13 -0700221 {1, UPB_SIZE(8, 8), 2, 0, 9, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700222 {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
Paul Yang57b65972019-03-19 22:27:13 -0700223 {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800224};
225
Paul Yang9bda1f12018-09-22 18:57:43 -0700226const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800227 &google_protobuf_EnumValueDescriptorProto_submsgs[0],
228 &google_protobuf_EnumValueDescriptorProto__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700229 UPB_SIZE(24, 32), 3, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800230};
231
Paul Yang9bda1f12018-09-22 18:57:43 -0700232static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800233 &google_protobuf_MethodDescriptorProto_msginit,
234 &google_protobuf_ServiceOptions_msginit,
235};
236
Paul Yang9bda1f12018-09-22 18:57:43 -0700237static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
Paul Yang57b65972019-03-19 22:27:13 -0700238 {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
239 {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
240 {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800241};
242
Paul Yang9bda1f12018-09-22 18:57:43 -0700243const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800244 &google_protobuf_ServiceDescriptorProto_submsgs[0],
245 &google_protobuf_ServiceDescriptorProto__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700246 UPB_SIZE(24, 48), 3, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800247};
248
Paul Yang9bda1f12018-09-22 18:57:43 -0700249static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800250 &google_protobuf_MethodOptions_msginit,
251};
252
Paul Yang9bda1f12018-09-22 18:57:43 -0700253static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
Paul Yang57b65972019-03-19 22:27:13 -0700254 {1, UPB_SIZE(4, 8), 3, 0, 9, 1},
255 {2, UPB_SIZE(12, 24), 4, 0, 9, 1},
256 {3, UPB_SIZE(20, 40), 5, 0, 9, 1},
257 {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700258 {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
259 {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800260};
261
Paul Yang9bda1f12018-09-22 18:57:43 -0700262const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800263 &google_protobuf_MethodDescriptorProto_submsgs[0],
264 &google_protobuf_MethodDescriptorProto__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700265 UPB_SIZE(32, 64), 6, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800266};
267
Paul Yang9bda1f12018-09-22 18:57:43 -0700268static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800269 &google_protobuf_UninterpretedOption_msginit,
270};
271
Paul Yang9bda1f12018-09-22 18:57:43 -0700272static const upb_msglayout_field google_protobuf_FileOptions__fields[19] = {
Paul Yang57b65972019-03-19 22:27:13 -0700273 {1, UPB_SIZE(28, 32), 11, 0, 9, 1},
274 {8, UPB_SIZE(36, 48), 12, 0, 9, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700275 {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
276 {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
Paul Yang57b65972019-03-19 22:27:13 -0700277 {11, UPB_SIZE(44, 64), 13, 0, 9, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700278 {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
279 {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
280 {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
281 {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
282 {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
283 {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
284 {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
Paul Yang57b65972019-03-19 22:27:13 -0700285 {36, UPB_SIZE(52, 80), 14, 0, 9, 1},
286 {37, UPB_SIZE(60, 96), 15, 0, 9, 1},
287 {39, UPB_SIZE(68, 112), 16, 0, 9, 1},
288 {40, UPB_SIZE(76, 128), 17, 0, 9, 1},
289 {41, UPB_SIZE(84, 144), 18, 0, 9, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700290 {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
Paul Yang57b65972019-03-19 22:27:13 -0700291 {999, UPB_SIZE(92, 160), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800292};
293
Paul Yang9bda1f12018-09-22 18:57:43 -0700294const upb_msglayout google_protobuf_FileOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800295 &google_protobuf_FileOptions_submsgs[0],
296 &google_protobuf_FileOptions__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700297 UPB_SIZE(96, 176), 19, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800298};
299
Paul Yang9bda1f12018-09-22 18:57:43 -0700300static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800301 &google_protobuf_UninterpretedOption_msginit,
302};
303
Paul Yang9bda1f12018-09-22 18:57:43 -0700304static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
305 {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
306 {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
307 {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
308 {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
309 {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800310};
311
Paul Yang9bda1f12018-09-22 18:57:43 -0700312const upb_msglayout google_protobuf_MessageOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800313 &google_protobuf_MessageOptions_submsgs[0],
314 &google_protobuf_MessageOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700315 UPB_SIZE(12, 16), 5, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800316};
317
Paul Yang9bda1f12018-09-22 18:57:43 -0700318static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800319 &google_protobuf_UninterpretedOption_msginit,
320};
321
Paul Yang9bda1f12018-09-22 18:57:43 -0700322static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
323 {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
324 {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
325 {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
326 {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
327 {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
328 {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
329 {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800330};
331
Paul Yang9bda1f12018-09-22 18:57:43 -0700332const upb_msglayout google_protobuf_FieldOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800333 &google_protobuf_FieldOptions_submsgs[0],
334 &google_protobuf_FieldOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700335 UPB_SIZE(32, 40), 7, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800336};
337
Paul Yang9bda1f12018-09-22 18:57:43 -0700338static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800339 &google_protobuf_UninterpretedOption_msginit,
340};
341
Paul Yang9bda1f12018-09-22 18:57:43 -0700342static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
343 {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800344};
345
Paul Yang9bda1f12018-09-22 18:57:43 -0700346const upb_msglayout google_protobuf_OneofOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800347 &google_protobuf_OneofOptions_submsgs[0],
348 &google_protobuf_OneofOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700349 UPB_SIZE(4, 8), 1, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800350};
351
Paul Yang9bda1f12018-09-22 18:57:43 -0700352static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800353 &google_protobuf_UninterpretedOption_msginit,
354};
355
Paul Yang9bda1f12018-09-22 18:57:43 -0700356static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
357 {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
358 {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
359 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800360};
361
Paul Yang9bda1f12018-09-22 18:57:43 -0700362const upb_msglayout google_protobuf_EnumOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800363 &google_protobuf_EnumOptions_submsgs[0],
364 &google_protobuf_EnumOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700365 UPB_SIZE(8, 16), 3, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800366};
367
Paul Yang9bda1f12018-09-22 18:57:43 -0700368static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800369 &google_protobuf_UninterpretedOption_msginit,
370};
371
Paul Yang9bda1f12018-09-22 18:57:43 -0700372static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
373 {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
374 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800375};
376
Paul Yang9bda1f12018-09-22 18:57:43 -0700377const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800378 &google_protobuf_EnumValueOptions_submsgs[0],
379 &google_protobuf_EnumValueOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700380 UPB_SIZE(8, 16), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800381};
382
Paul Yang9bda1f12018-09-22 18:57:43 -0700383static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800384 &google_protobuf_UninterpretedOption_msginit,
385};
386
Paul Yang9bda1f12018-09-22 18:57:43 -0700387static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
388 {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
389 {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800390};
391
Paul Yang9bda1f12018-09-22 18:57:43 -0700392const upb_msglayout google_protobuf_ServiceOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800393 &google_protobuf_ServiceOptions_submsgs[0],
394 &google_protobuf_ServiceOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700395 UPB_SIZE(8, 16), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800396};
397
Paul Yang9bda1f12018-09-22 18:57:43 -0700398static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800399 &google_protobuf_UninterpretedOption_msginit,
400};
401
Paul Yang9bda1f12018-09-22 18:57:43 -0700402static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
403 {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
404 {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
405 {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800406};
407
Paul Yang9bda1f12018-09-22 18:57:43 -0700408const upb_msglayout google_protobuf_MethodOptions_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800409 &google_protobuf_MethodOptions_submsgs[0],
410 &google_protobuf_MethodOptions__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700411 UPB_SIZE(24, 32), 3, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800412};
413
Paul Yang9bda1f12018-09-22 18:57:43 -0700414static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800415 &google_protobuf_UninterpretedOption_NamePart_msginit,
416};
417
Paul Yang9bda1f12018-09-22 18:57:43 -0700418static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
419 {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
420 {3, UPB_SIZE(32, 32), 4, 0, 9, 1},
421 {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
422 {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
423 {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
424 {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
425 {8, UPB_SIZE(48, 64), 6, 0, 9, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800426};
427
Paul Yang9bda1f12018-09-22 18:57:43 -0700428const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800429 &google_protobuf_UninterpretedOption_submsgs[0],
430 &google_protobuf_UninterpretedOption__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700431 UPB_SIZE(64, 96), 7, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800432};
433
Paul Yang9bda1f12018-09-22 18:57:43 -0700434static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
Paul Yang57b65972019-03-19 22:27:13 -0700435 {1, UPB_SIZE(4, 8), 2, 0, 9, 2},
Paul Yang9bda1f12018-09-22 18:57:43 -0700436 {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
Paul Yang6dd563a2018-03-08 17:35:22 -0800437};
438
Paul Yang9bda1f12018-09-22 18:57:43 -0700439const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800440 NULL,
441 &google_protobuf_UninterpretedOption_NamePart__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700442 UPB_SIZE(16, 32), 2, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800443};
444
Paul Yang9bda1f12018-09-22 18:57:43 -0700445static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800446 &google_protobuf_SourceCodeInfo_Location_msginit,
447};
448
Paul Yang9bda1f12018-09-22 18:57:43 -0700449static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
450 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800451};
452
Paul Yang9bda1f12018-09-22 18:57:43 -0700453const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800454 &google_protobuf_SourceCodeInfo_submsgs[0],
455 &google_protobuf_SourceCodeInfo__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700456 UPB_SIZE(4, 8), 1, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800457};
458
Paul Yang9bda1f12018-09-22 18:57:43 -0700459static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
Paul Yang57b65972019-03-19 22:27:13 -0700460 {1, UPB_SIZE(20, 40), 0, 0, 5, 3},
461 {2, UPB_SIZE(24, 48), 0, 0, 5, 3},
462 {3, UPB_SIZE(4, 8), 1, 0, 9, 1},
463 {4, UPB_SIZE(12, 24), 2, 0, 9, 1},
464 {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800465};
466
Paul Yang9bda1f12018-09-22 18:57:43 -0700467const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800468 NULL,
469 &google_protobuf_SourceCodeInfo_Location__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700470 UPB_SIZE(32, 64), 5, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800471};
472
Paul Yang9bda1f12018-09-22 18:57:43 -0700473static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800474 &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
475};
476
Paul Yang9bda1f12018-09-22 18:57:43 -0700477static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
478 {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
Paul Yang6dd563a2018-03-08 17:35:22 -0800479};
480
Paul Yang9bda1f12018-09-22 18:57:43 -0700481const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800482 &google_protobuf_GeneratedCodeInfo_submsgs[0],
483 &google_protobuf_GeneratedCodeInfo__fields[0],
Paul Yang9bda1f12018-09-22 18:57:43 -0700484 UPB_SIZE(4, 8), 1, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800485};
486
Paul Yang9bda1f12018-09-22 18:57:43 -0700487static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
Paul Yang57b65972019-03-19 22:27:13 -0700488 {1, UPB_SIZE(20, 32), 0, 0, 5, 3},
489 {2, UPB_SIZE(12, 16), 3, 0, 9, 1},
Paul Yang9bda1f12018-09-22 18:57:43 -0700490 {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
491 {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
Paul Yang6dd563a2018-03-08 17:35:22 -0800492};
493
Paul Yang9bda1f12018-09-22 18:57:43 -0700494const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
Paul Yang6dd563a2018-03-08 17:35:22 -0800495 NULL,
496 &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
Paul Yang57b65972019-03-19 22:27:13 -0700497 UPB_SIZE(24, 48), 4, false,
Paul Yang6dd563a2018-03-08 17:35:22 -0800498};
499
Paul Yang9bda1f12018-09-22 18:57:43 -0700500
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700501
502
Paul Yang60327462017-10-09 12:39:13 -0700503/* Maps descriptor type -> upb field type. */
Paul Yang6dd563a2018-03-08 17:35:22 -0800504const uint8_t upb_desctype_to_fieldtype[] = {
Paul Yang60327462017-10-09 12:39:13 -0700505 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
506 UPB_TYPE_DOUBLE, /* DOUBLE */
507 UPB_TYPE_FLOAT, /* FLOAT */
508 UPB_TYPE_INT64, /* INT64 */
509 UPB_TYPE_UINT64, /* UINT64 */
510 UPB_TYPE_INT32, /* INT32 */
511 UPB_TYPE_UINT64, /* FIXED64 */
512 UPB_TYPE_UINT32, /* FIXED32 */
513 UPB_TYPE_BOOL, /* BOOL */
514 UPB_TYPE_STRING, /* STRING */
515 UPB_TYPE_MESSAGE, /* GROUP */
516 UPB_TYPE_MESSAGE, /* MESSAGE */
517 UPB_TYPE_BYTES, /* BYTES */
518 UPB_TYPE_UINT32, /* UINT32 */
519 UPB_TYPE_ENUM, /* ENUM */
520 UPB_TYPE_INT32, /* SFIXED32 */
521 UPB_TYPE_INT64, /* SFIXED64 */
522 UPB_TYPE_INT32, /* SINT32 */
523 UPB_TYPE_INT64, /* SINT64 */
524};
525
526/* Data pertaining to the parse. */
527typedef struct {
Paul Yang60327462017-10-09 12:39:13 -0700528 /* Current decoding pointer. Points to the beginning of a field until we
529 * have finished decoding the whole field. */
530 const char *ptr;
531} upb_decstate;
532
533/* Data pertaining to a single message frame. */
534typedef struct {
535 const char *limit;
536 int32_t group_number; /* 0 if we are not parsing a group. */
537
538 /* These members are unset for an unknown group frame. */
539 char *msg;
Paul Yang9bda1f12018-09-22 18:57:43 -0700540 const upb_msglayout *m;
Paul Yang60327462017-10-09 12:39:13 -0700541} upb_decframe;
542
543#define CHK(x) if (!(x)) { return false; }
544
545static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
546 const char *limit);
547static bool upb_decode_message(upb_decstate *d, const char *limit,
548 int group_number, char *msg,
Paul Yang9bda1f12018-09-22 18:57:43 -0700549 const upb_msglayout *l);
Paul Yang60327462017-10-09 12:39:13 -0700550
551static bool upb_decode_varint(const char **ptr, const char *limit,
552 uint64_t *val) {
553 uint8_t byte;
554 int bitpos = 0;
555 const char *p = *ptr;
556 *val = 0;
557
558 do {
559 CHK(bitpos < 70 && p < limit);
560 byte = *p;
561 *val |= (uint64_t)(byte & 0x7F) << bitpos;
562 p++;
563 bitpos += 7;
564 } while (byte & 0x80);
565
566 *ptr = p;
567 return true;
568}
569
570static bool upb_decode_varint32(const char **ptr, const char *limit,
571 uint32_t *val) {
572 uint64_t u64;
573 CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
574 *val = u64;
575 return true;
576}
577
578static bool upb_decode_64bit(const char **ptr, const char *limit,
579 uint64_t *val) {
580 CHK(limit - *ptr >= 8);
581 memcpy(val, *ptr, 8);
582 *ptr += 8;
583 return true;
584}
585
586static bool upb_decode_32bit(const char **ptr, const char *limit,
587 uint32_t *val) {
588 CHK(limit - *ptr >= 4);
589 memcpy(val, *ptr, 4);
590 *ptr += 4;
591 return true;
592}
593
594static bool upb_decode_tag(const char **ptr, const char *limit,
595 int *field_number, int *wire_type) {
596 uint32_t tag = 0;
597 CHK(upb_decode_varint32(ptr, limit, &tag));
598 *field_number = tag >> 3;
599 *wire_type = tag & 7;
600 return true;
601}
602
603static int32_t upb_zzdecode_32(uint32_t n) {
604 return (n >> 1) ^ -(int32_t)(n & 1);
605}
606
607static int64_t upb_zzdecode_64(uint64_t n) {
608 return (n >> 1) ^ -(int64_t)(n & 1);
609}
610
611static bool upb_decode_string(const char **ptr, const char *limit,
Paul Yang57b65972019-03-19 22:27:13 -0700612 upb_strview *val) {
Paul Yang60327462017-10-09 12:39:13 -0700613 uint32_t len;
614
615 CHK(upb_decode_varint32(ptr, limit, &len) &&
616 len < INT32_MAX &&
617 limit - *ptr >= (int32_t)len);
618
Paul Yang57b65972019-03-19 22:27:13 -0700619 *val = upb_strview_make(*ptr, len);
Paul Yang60327462017-10-09 12:39:13 -0700620 *ptr += len;
621 return true;
622}
623
624static void upb_set32(void *msg, size_t ofs, uint32_t val) {
625 memcpy((char*)msg + ofs, &val, sizeof(val));
626}
627
628static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
629 const char *start) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700630 upb_msg_addunknown(frame->msg, start, d->ptr - start);
Paul Yang60327462017-10-09 12:39:13 -0700631 return true;
632}
633
634static bool upb_skip_unknownfielddata(upb_decstate *d, upb_decframe *frame,
635 int field_number, int wire_type) {
636 switch (wire_type) {
637 case UPB_WIRE_TYPE_VARINT: {
638 uint64_t val;
639 return upb_decode_varint(&d->ptr, frame->limit, &val);
640 }
641 case UPB_WIRE_TYPE_32BIT: {
642 uint32_t val;
643 return upb_decode_32bit(&d->ptr, frame->limit, &val);
644 }
645 case UPB_WIRE_TYPE_64BIT: {
646 uint64_t val;
647 return upb_decode_64bit(&d->ptr, frame->limit, &val);
648 }
649 case UPB_WIRE_TYPE_DELIMITED: {
Paul Yang57b65972019-03-19 22:27:13 -0700650 upb_strview val;
Paul Yang60327462017-10-09 12:39:13 -0700651 return upb_decode_string(&d->ptr, frame->limit, &val);
652 }
653 case UPB_WIRE_TYPE_START_GROUP:
654 return upb_skip_unknowngroup(d, field_number, frame->limit);
655 case UPB_WIRE_TYPE_END_GROUP:
656 CHK(field_number == frame->group_number);
657 frame->limit = d->ptr;
658 return true;
659 }
660 return false;
661}
662
663static bool upb_array_grow(upb_array *arr, size_t elements) {
664 size_t needed = arr->len + elements;
665 size_t new_size = UPB_MAX(arr->size, 8);
666 size_t new_bytes;
667 size_t old_bytes;
668 void *new_data;
Paul Yang9bda1f12018-09-22 18:57:43 -0700669 upb_alloc *alloc = upb_arena_alloc(arr->arena);
Paul Yang60327462017-10-09 12:39:13 -0700670
671 while (new_size < needed) {
672 new_size *= 2;
673 }
674
675 old_bytes = arr->len * arr->element_size;
676 new_bytes = new_size * arr->element_size;
Paul Yang9bda1f12018-09-22 18:57:43 -0700677 new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes);
Paul Yang60327462017-10-09 12:39:13 -0700678 CHK(new_data);
679
680 arr->data = new_data;
681 arr->size = new_size;
682 return true;
683}
684
685static void *upb_array_reserve(upb_array *arr, size_t elements) {
686 if (arr->size - arr->len < elements) {
687 CHK(upb_array_grow(arr, elements));
688 }
689 return (char*)arr->data + (arr->len * arr->element_size);
690}
691
692static void *upb_array_add(upb_array *arr, size_t elements) {
693 void *ret = upb_array_reserve(arr, elements);
694 arr->len += elements;
695 return ret;
696}
697
698static upb_array *upb_getarr(upb_decframe *frame,
Paul Yang9bda1f12018-09-22 18:57:43 -0700699 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700700 UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
701 return *(upb_array**)&frame->msg[field->offset];
702}
703
Paul Yang9bda1f12018-09-22 18:57:43 -0700704static upb_array *upb_getorcreatearr(upb_decframe *frame,
705 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700706 upb_array *arr = upb_getarr(frame, field);
707
708 if (!arr) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700709 upb_fieldtype_t type = upb_desctype_to_fieldtype[field->descriptortype];
710 arr = upb_array_new(type, upb_msg_arena(frame->msg));
Paul Yang60327462017-10-09 12:39:13 -0700711 if (!arr) {
712 return NULL;
713 }
Paul Yang60327462017-10-09 12:39:13 -0700714 *(upb_array**)&frame->msg[field->offset] = arr;
715 }
716
717 return arr;
718}
719
720static void upb_sethasbit(upb_decframe *frame,
Paul Yang9bda1f12018-09-22 18:57:43 -0700721 const upb_msglayout_field *field) {
722 int32_t hasbit = field->presence;
723 UPB_ASSERT(field->presence > 0);
724 frame->msg[hasbit / 8] |= (1 << (hasbit % 8));
Paul Yang60327462017-10-09 12:39:13 -0700725}
726
727static void upb_setoneofcase(upb_decframe *frame,
Paul Yang9bda1f12018-09-22 18:57:43 -0700728 const upb_msglayout_field *field) {
729 UPB_ASSERT(field->presence < 0);
730 upb_set32(frame->msg, ~field->presence, field->number);
Paul Yang60327462017-10-09 12:39:13 -0700731}
732
Paul Yang9bda1f12018-09-22 18:57:43 -0700733static char *upb_decode_prepareslot(upb_decframe *frame,
734 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700735 char *field_mem = frame->msg + field->offset;
736 upb_array *arr;
737
738 if (field->label == UPB_LABEL_REPEATED) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700739 arr = upb_getorcreatearr(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700740 field_mem = upb_array_reserve(arr, 1);
741 }
742
743 return field_mem;
744}
745
746static void upb_decode_setpresent(upb_decframe *frame,
Paul Yang9bda1f12018-09-22 18:57:43 -0700747 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700748 if (field->label == UPB_LABEL_REPEATED) {
749 upb_array *arr = upb_getarr(frame, field);
750 UPB_ASSERT(arr->len < arr->size);
751 arr->len++;
Paul Yang9bda1f12018-09-22 18:57:43 -0700752 } else if (field->presence < 0) {
Paul Yang60327462017-10-09 12:39:13 -0700753 upb_setoneofcase(frame, field);
Paul Yang9bda1f12018-09-22 18:57:43 -0700754 } else if (field->presence > 0) {
Paul Yang60327462017-10-09 12:39:13 -0700755 upb_sethasbit(frame, field);
756 }
757}
758
Paul Yang9bda1f12018-09-22 18:57:43 -0700759static bool upb_decode_submsg(upb_decstate *d, upb_decframe *frame,
Paul Yang60327462017-10-09 12:39:13 -0700760 const char *limit,
Paul Yang9bda1f12018-09-22 18:57:43 -0700761 const upb_msglayout_field *field,
Paul Yang60327462017-10-09 12:39:13 -0700762 int group_number) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700763 char *submsg_slot = upb_decode_prepareslot(frame, field);
764 char *submsg = *(void **)submsg_slot;
765 const upb_msglayout *subm;
Paul Yang60327462017-10-09 12:39:13 -0700766
Paul Yang60327462017-10-09 12:39:13 -0700767 subm = frame->m->submsgs[field->submsg_index];
768 UPB_ASSERT(subm);
769
770 if (!submsg) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700771 submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
Paul Yang60327462017-10-09 12:39:13 -0700772 CHK(submsg);
Paul Yang6dd563a2018-03-08 17:35:22 -0800773 *(void**)submsg_slot = submsg;
Paul Yang60327462017-10-09 12:39:13 -0700774 }
775
776 upb_decode_message(d, limit, group_number, submsg, subm);
777
778 return true;
779}
780
781static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
782 const char *field_start,
Paul Yang9bda1f12018-09-22 18:57:43 -0700783 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700784 uint64_t val;
785 void *field_mem;
786
Paul Yang9bda1f12018-09-22 18:57:43 -0700787 field_mem = upb_decode_prepareslot(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700788 CHK(field_mem);
789 CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
790
Paul Yang0f4ad852018-03-06 13:30:03 -0800791 switch ((upb_descriptortype_t)field->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -0700792 case UPB_DESCRIPTOR_TYPE_INT64:
793 case UPB_DESCRIPTOR_TYPE_UINT64:
794 memcpy(field_mem, &val, sizeof(val));
795 break;
796 case UPB_DESCRIPTOR_TYPE_INT32:
797 case UPB_DESCRIPTOR_TYPE_UINT32:
798 case UPB_DESCRIPTOR_TYPE_ENUM: {
799 uint32_t val32 = val;
800 memcpy(field_mem, &val32, sizeof(val32));
801 break;
802 }
803 case UPB_DESCRIPTOR_TYPE_BOOL: {
804 bool valbool = val != 0;
805 memcpy(field_mem, &valbool, sizeof(valbool));
806 break;
807 }
808 case UPB_DESCRIPTOR_TYPE_SINT32: {
809 int32_t decoded = upb_zzdecode_32(val);
810 memcpy(field_mem, &decoded, sizeof(decoded));
811 break;
812 }
813 case UPB_DESCRIPTOR_TYPE_SINT64: {
814 int64_t decoded = upb_zzdecode_64(val);
815 memcpy(field_mem, &decoded, sizeof(decoded));
816 break;
817 }
818 default:
819 return upb_append_unknown(d, frame, field_start);
820 }
821
822 upb_decode_setpresent(frame, field);
823 return true;
824}
825
826static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
827 const char *field_start,
Paul Yang9bda1f12018-09-22 18:57:43 -0700828 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700829 void *field_mem;
830 uint64_t val;
831
Paul Yang9bda1f12018-09-22 18:57:43 -0700832 field_mem = upb_decode_prepareslot(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700833 CHK(field_mem);
834 CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
835
Paul Yang0f4ad852018-03-06 13:30:03 -0800836 switch ((upb_descriptortype_t)field->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -0700837 case UPB_DESCRIPTOR_TYPE_DOUBLE:
838 case UPB_DESCRIPTOR_TYPE_FIXED64:
839 case UPB_DESCRIPTOR_TYPE_SFIXED64:
840 memcpy(field_mem, &val, sizeof(val));
841 break;
842 default:
843 return upb_append_unknown(d, frame, field_start);
844 }
845
846 upb_decode_setpresent(frame, field);
847 return true;
848}
849
850static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
851 const char *field_start,
Paul Yang9bda1f12018-09-22 18:57:43 -0700852 const upb_msglayout_field *field) {
Paul Yang60327462017-10-09 12:39:13 -0700853 void *field_mem;
854 uint32_t val;
855
Paul Yang9bda1f12018-09-22 18:57:43 -0700856 field_mem = upb_decode_prepareslot(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700857 CHK(field_mem);
858 CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
859
Paul Yang0f4ad852018-03-06 13:30:03 -0800860 switch ((upb_descriptortype_t)field->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -0700861 case UPB_DESCRIPTOR_TYPE_FLOAT:
862 case UPB_DESCRIPTOR_TYPE_FIXED32:
863 case UPB_DESCRIPTOR_TYPE_SFIXED32:
864 memcpy(field_mem, &val, sizeof(val));
865 break;
866 default:
867 return upb_append_unknown(d, frame, field_start);
868 }
869
870 upb_decode_setpresent(frame, field);
871 return true;
872}
873
Paul Yang57b65972019-03-19 22:27:13 -0700874static bool upb_decode_fixedpacked(upb_array *arr, upb_strview data,
Paul Yang60327462017-10-09 12:39:13 -0700875 int elem_size) {
876 int elements = data.size / elem_size;
877 void *field_mem;
878
879 CHK((size_t)(elements * elem_size) == data.size);
880 field_mem = upb_array_add(arr, elements);
881 CHK(field_mem);
882 memcpy(field_mem, data.data, data.size);
883 return true;
884}
885
886static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
887 const char *field_start,
Paul Yang9bda1f12018-09-22 18:57:43 -0700888 const upb_msglayout_field *field,
Paul Yang57b65972019-03-19 22:27:13 -0700889 upb_strview val) {
Paul Yang9bda1f12018-09-22 18:57:43 -0700890 upb_array *arr = upb_getorcreatearr(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700891
892#define VARINT_CASE(ctype, decode) { \
893 const char *ptr = val.data; \
894 const char *limit = ptr + val.size; \
895 while (ptr < limit) { \
896 uint64_t val; \
897 void *field_mem; \
898 ctype decoded; \
899 CHK(upb_decode_varint(&ptr, limit, &val)); \
900 decoded = (decode)(val); \
901 field_mem = upb_array_add(arr, 1); \
902 CHK(field_mem); \
903 memcpy(field_mem, &decoded, sizeof(ctype)); \
904 } \
905 return true; \
906}
907
Paul Yang0f4ad852018-03-06 13:30:03 -0800908 switch ((upb_descriptortype_t)field->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -0700909 case UPB_DESCRIPTOR_TYPE_STRING:
910 case UPB_DESCRIPTOR_TYPE_BYTES: {
911 void *field_mem = upb_array_add(arr, 1);
912 CHK(field_mem);
913 memcpy(field_mem, &val, sizeof(val));
914 return true;
915 }
916 case UPB_DESCRIPTOR_TYPE_FLOAT:
917 case UPB_DESCRIPTOR_TYPE_FIXED32:
918 case UPB_DESCRIPTOR_TYPE_SFIXED32:
919 return upb_decode_fixedpacked(arr, val, sizeof(int32_t));
920 case UPB_DESCRIPTOR_TYPE_DOUBLE:
921 case UPB_DESCRIPTOR_TYPE_FIXED64:
922 case UPB_DESCRIPTOR_TYPE_SFIXED64:
923 return upb_decode_fixedpacked(arr, val, sizeof(int64_t));
924 case UPB_DESCRIPTOR_TYPE_INT32:
925 case UPB_DESCRIPTOR_TYPE_UINT32:
926 case UPB_DESCRIPTOR_TYPE_ENUM:
927 /* TODO: proto2 enum field that isn't in the enum. */
928 VARINT_CASE(uint32_t, uint32_t);
929 case UPB_DESCRIPTOR_TYPE_INT64:
930 case UPB_DESCRIPTOR_TYPE_UINT64:
931 VARINT_CASE(uint64_t, uint64_t);
932 case UPB_DESCRIPTOR_TYPE_BOOL:
933 VARINT_CASE(bool, bool);
934 case UPB_DESCRIPTOR_TYPE_SINT32:
935 VARINT_CASE(int32_t, upb_zzdecode_32);
936 case UPB_DESCRIPTOR_TYPE_SINT64:
937 VARINT_CASE(int64_t, upb_zzdecode_64);
Paul Yang6dd563a2018-03-08 17:35:22 -0800938 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
Paul Yang9bda1f12018-09-22 18:57:43 -0700939 const upb_msglayout *subm;
Paul Yang6dd563a2018-03-08 17:35:22 -0800940 char *submsg;
941 void *field_mem;
942
Paul Yang60327462017-10-09 12:39:13 -0700943 CHK(val.size <= (size_t)(frame->limit - val.data));
Paul Yang6dd563a2018-03-08 17:35:22 -0800944 d->ptr -= val.size;
945
946 /* Create elemente message. */
Paul Yang6dd563a2018-03-08 17:35:22 -0800947 subm = frame->m->submsgs[field->submsg_index];
948 UPB_ASSERT(subm);
949
Paul Yang9bda1f12018-09-22 18:57:43 -0700950 submsg = upb_msg_new(subm, upb_msg_arena(frame->msg));
Paul Yang6dd563a2018-03-08 17:35:22 -0800951 CHK(submsg);
Paul Yang6dd563a2018-03-08 17:35:22 -0800952
953 field_mem = upb_array_add(arr, 1);
954 CHK(field_mem);
955 *(void**)field_mem = submsg;
956
957 return upb_decode_message(
958 d, val.data + val.size, frame->group_number, submsg, subm);
959 }
Paul Yang60327462017-10-09 12:39:13 -0700960 case UPB_DESCRIPTOR_TYPE_GROUP:
961 return upb_append_unknown(d, frame, field_start);
962 }
963#undef VARINT_CASE
964 UPB_UNREACHABLE();
965}
966
967static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
968 const char *field_start,
Paul Yang9bda1f12018-09-22 18:57:43 -0700969 const upb_msglayout_field *field) {
Paul Yang57b65972019-03-19 22:27:13 -0700970 upb_strview val;
Paul Yang60327462017-10-09 12:39:13 -0700971
972 CHK(upb_decode_string(&d->ptr, frame->limit, &val));
973
974 if (field->label == UPB_LABEL_REPEATED) {
975 return upb_decode_toarray(d, frame, field_start, field, val);
976 } else {
Paul Yang0f4ad852018-03-06 13:30:03 -0800977 switch ((upb_descriptortype_t)field->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -0700978 case UPB_DESCRIPTOR_TYPE_STRING:
979 case UPB_DESCRIPTOR_TYPE_BYTES: {
Paul Yang9bda1f12018-09-22 18:57:43 -0700980 void *field_mem = upb_decode_prepareslot(frame, field);
Paul Yang60327462017-10-09 12:39:13 -0700981 CHK(field_mem);
982 memcpy(field_mem, &val, sizeof(val));
983 break;
984 }
985 case UPB_DESCRIPTOR_TYPE_MESSAGE:
986 CHK(val.size <= (size_t)(frame->limit - val.data));
Paul Yang6dd563a2018-03-08 17:35:22 -0800987 d->ptr -= val.size;
Paul Yang60327462017-10-09 12:39:13 -0700988 CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
989 break;
990 default:
991 /* TODO(haberman): should we accept the last element of a packed? */
992 return upb_append_unknown(d, frame, field_start);
993 }
994 upb_decode_setpresent(frame, field);
995 return true;
996 }
997}
998
Paul Yang9bda1f12018-09-22 18:57:43 -0700999static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
1000 uint32_t field_number) {
Paul Yang60327462017-10-09 12:39:13 -07001001 /* Lots of optimization opportunities here. */
1002 int i;
1003 for (i = 0; i < l->field_count; i++) {
1004 if (l->fields[i].number == field_number) {
1005 return &l->fields[i];
1006 }
1007 }
1008
1009 return NULL; /* Unknown field. */
1010}
1011
1012static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
1013 int field_number;
1014 int wire_type;
1015 const char *field_start = d->ptr;
Paul Yang9bda1f12018-09-22 18:57:43 -07001016 const upb_msglayout_field *field;
Paul Yang60327462017-10-09 12:39:13 -07001017
1018 CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
1019 field = upb_find_field(frame->m, field_number);
1020
1021 if (field) {
1022 switch (wire_type) {
1023 case UPB_WIRE_TYPE_VARINT:
1024 return upb_decode_varintfield(d, frame, field_start, field);
1025 case UPB_WIRE_TYPE_32BIT:
1026 return upb_decode_32bitfield(d, frame, field_start, field);
1027 case UPB_WIRE_TYPE_64BIT:
1028 return upb_decode_64bitfield(d, frame, field_start, field);
1029 case UPB_WIRE_TYPE_DELIMITED:
1030 return upb_decode_delimitedfield(d, frame, field_start, field);
1031 case UPB_WIRE_TYPE_START_GROUP:
Paul Yang0f4ad852018-03-06 13:30:03 -08001032 CHK(field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
Paul Yang60327462017-10-09 12:39:13 -07001033 return upb_decode_submsg(d, frame, frame->limit, field, field_number);
1034 case UPB_WIRE_TYPE_END_GROUP:
1035 CHK(frame->group_number == field_number)
1036 frame->limit = d->ptr;
1037 return true;
1038 default:
1039 return false;
1040 }
1041 } else {
1042 CHK(field_number != 0);
Paul Yang9bda1f12018-09-22 18:57:43 -07001043 CHK(upb_skip_unknownfielddata(d, frame, field_number, wire_type));
1044 CHK(upb_append_unknown(d, frame, field_start));
1045 return true;
Paul Yang60327462017-10-09 12:39:13 -07001046 }
1047}
1048
1049static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
1050 const char *limit) {
1051 upb_decframe frame;
1052 frame.msg = NULL;
1053 frame.m = NULL;
1054 frame.group_number = field_number;
1055 frame.limit = limit;
1056
1057 while (d->ptr < frame.limit) {
1058 int wire_type;
1059 int field_number;
1060
1061 CHK(upb_decode_tag(&d->ptr, frame.limit, &field_number, &wire_type));
1062 CHK(upb_skip_unknownfielddata(d, &frame, field_number, wire_type));
1063 }
1064
1065 return true;
1066}
1067
1068static bool upb_decode_message(upb_decstate *d, const char *limit,
1069 int group_number, char *msg,
Paul Yang9bda1f12018-09-22 18:57:43 -07001070 const upb_msglayout *l) {
Paul Yang60327462017-10-09 12:39:13 -07001071 upb_decframe frame;
1072 frame.group_number = group_number;
1073 frame.limit = limit;
1074 frame.msg = msg;
1075 frame.m = l;
1076
1077 while (d->ptr < frame.limit) {
1078 CHK(upb_decode_field(d, &frame));
1079 }
1080
1081 return true;
1082}
1083
Paul Yang57b65972019-03-19 22:27:13 -07001084bool upb_decode(upb_strview buf, void *msg, const upb_msglayout *l) {
Paul Yang60327462017-10-09 12:39:13 -07001085 upb_decstate state;
1086 state.ptr = buf.data;
Paul Yang60327462017-10-09 12:39:13 -07001087
1088 return upb_decode_message(&state, buf.data + buf.size, 0, msg, l);
1089}
1090
1091#undef CHK
1092
1093
Paul Yange0e54662016-09-15 11:09:01 -07001094#include <ctype.h>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001095#include <stdlib.h>
1096#include <string.h>
1097
1098typedef struct {
1099 size_t len;
1100 char str[1]; /* Null-terminated string data follows. */
1101} str_t;
1102
1103static str_t *newstr(const char *data, size_t len) {
Paul Yange0e54662016-09-15 11:09:01 -07001104 str_t *ret = upb_gmalloc(sizeof(*ret) + len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001105 if (!ret) return NULL;
1106 ret->len = len;
1107 memcpy(ret->str, data, len);
1108 ret->str[len] = '\0';
1109 return ret;
1110}
1111
Paul Yange0e54662016-09-15 11:09:01 -07001112static void freestr(str_t *s) { upb_gfree(s); }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001113
1114/* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
1115static bool upb_isbetween(char c, char low, char high) {
1116 return c >= low && c <= high;
1117}
1118
1119static bool upb_isletter(char c) {
1120 return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
1121}
1122
1123static bool upb_isalphanum(char c) {
1124 return upb_isletter(c) || upb_isbetween(c, '0', '9');
1125}
1126
1127static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
1128 bool start = true;
1129 size_t i;
1130 for (i = 0; i < len; i++) {
1131 char c = str[i];
1132 if (c == '.') {
1133 if (start || !full) {
1134 upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
1135 return false;
1136 }
1137 start = true;
1138 } else if (start) {
1139 if (!upb_isletter(c)) {
1140 upb_status_seterrf(
1141 s, "invalid name: path components must start with a letter (%s)",
1142 str);
1143 return false;
1144 }
1145 start = false;
1146 } else {
1147 if (!upb_isalphanum(c)) {
1148 upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
1149 str);
1150 return false;
1151 }
1152 }
1153 }
1154 return !start;
1155}
1156
Paul Yange0e54662016-09-15 11:09:01 -07001157static bool upb_isoneof(const upb_refcounted *def) {
1158 return def->vtbl == &upb_oneofdef_vtbl;
1159}
1160
1161static bool upb_isfield(const upb_refcounted *def) {
1162 return def->vtbl == &upb_fielddef_vtbl;
1163}
1164
1165static const upb_oneofdef *upb_trygetoneof(const upb_refcounted *def) {
1166 return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL;
1167}
1168
1169static const upb_fielddef *upb_trygetfield(const upb_refcounted *def) {
1170 return upb_isfield(def) ? (const upb_fielddef*)def : NULL;
1171}
1172
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001173
1174/* upb_def ********************************************************************/
1175
1176upb_deftype_t upb_def_type(const upb_def *d) { return d->type; }
1177
1178const char *upb_def_fullname(const upb_def *d) { return d->fullname; }
1179
Paul Yange0e54662016-09-15 11:09:01 -07001180const char *upb_def_name(const upb_def *d) {
1181 const char *p;
1182
1183 if (d->fullname == NULL) {
1184 return NULL;
1185 } else if ((p = strrchr(d->fullname, '.')) == NULL) {
1186 /* No '.' in the name, return the full string. */
1187 return d->fullname;
1188 } else {
1189 /* Return one past the last '.'. */
1190 return p + 1;
1191 }
1192}
1193
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001194bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07001195 UPB_ASSERT(!upb_def_isfrozen(def));
1196 if (!upb_isident(fullname, strlen(fullname), true, s)) {
1197 return false;
1198 }
1199
1200 fullname = upb_gstrdup(fullname);
1201 if (!fullname) {
1202 upb_upberr_setoom(s);
1203 return false;
1204 }
1205
1206 upb_gfree((void*)def->fullname);
1207 def->fullname = fullname;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001208 return true;
1209}
1210
Paul Yange0e54662016-09-15 11:09:01 -07001211const upb_filedef *upb_def_file(const upb_def *d) { return d->file; }
1212
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001213static bool upb_def_init(upb_def *def, upb_deftype_t type,
1214 const struct upb_refcounted_vtbl *vtbl,
1215 const void *owner) {
1216 if (!upb_refcounted_init(upb_def_upcast_mutable(def), vtbl, owner)) return false;
1217 def->type = type;
1218 def->fullname = NULL;
1219 def->came_from_user = false;
Paul Yange0e54662016-09-15 11:09:01 -07001220 def->file = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001221 return true;
1222}
1223
1224static void upb_def_uninit(upb_def *def) {
Paul Yange0e54662016-09-15 11:09:01 -07001225 upb_gfree((void*)def->fullname);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001226}
1227
1228static const char *msgdef_name(const upb_msgdef *m) {
1229 const char *name = upb_def_fullname(upb_msgdef_upcast(m));
1230 return name ? name : "(anonymous)";
1231}
1232
1233static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
1234 if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
1235 upb_status_seterrmsg(s, "fielddef must have name and number set");
1236 return false;
1237 }
1238
1239 if (!f->type_is_set_) {
1240 upb_status_seterrmsg(s, "fielddef type was not initialized");
1241 return false;
1242 }
1243
1244 if (upb_fielddef_lazy(f) &&
1245 upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) {
1246 upb_status_seterrmsg(s,
1247 "only length-delimited submessage fields may be lazy");
1248 return false;
1249 }
1250
1251 if (upb_fielddef_hassubdef(f)) {
1252 const upb_def *subdef;
1253
1254 if (f->subdef_is_symbolic) {
1255 upb_status_seterrf(s, "field '%s.%s' has not been resolved",
1256 msgdef_name(f->msg.def), upb_fielddef_name(f));
1257 return false;
1258 }
1259
1260 subdef = upb_fielddef_subdef(f);
1261 if (subdef == NULL) {
1262 upb_status_seterrf(s, "field %s.%s is missing required subdef",
1263 msgdef_name(f->msg.def), upb_fielddef_name(f));
1264 return false;
1265 }
1266
1267 if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
1268 upb_status_seterrf(s,
1269 "subdef of field %s.%s is not frozen or being frozen",
1270 msgdef_name(f->msg.def), upb_fielddef_name(f));
1271 return false;
1272 }
1273 }
1274
1275 if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
1276 bool has_default_name = upb_fielddef_enumhasdefaultstr(f);
1277 bool has_default_number = upb_fielddef_enumhasdefaultint32(f);
1278
1279 /* Previously verified by upb_validate_enumdef(). */
Paul Yange0e54662016-09-15 11:09:01 -07001280 UPB_ASSERT(upb_enumdef_numvals(upb_fielddef_enumsubdef(f)) > 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001281
1282 /* We've already validated that we have an associated enumdef and that it
1283 * has at least one member, so at least one of these should be true.
1284 * Because if the user didn't set anything, we'll pick up the enum's
1285 * default, but if the user *did* set something we should at least pick up
1286 * the one they set (int32 or string). */
Paul Yange0e54662016-09-15 11:09:01 -07001287 UPB_ASSERT(has_default_name || has_default_number);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001288
1289 if (!has_default_name) {
1290 upb_status_seterrf(s,
1291 "enum default for field %s.%s (%d) is not in the enum",
1292 msgdef_name(f->msg.def), upb_fielddef_name(f),
1293 upb_fielddef_defaultint32(f));
1294 return false;
1295 }
1296
1297 if (!has_default_number) {
1298 upb_status_seterrf(s,
1299 "enum default for field %s.%s (%s) is not in the enum",
1300 msgdef_name(f->msg.def), upb_fielddef_name(f),
1301 upb_fielddef_defaultstr(f, NULL));
1302 return false;
1303 }
1304
1305 /* Lift the effective numeric default into the field's default slot, in case
1306 * we were only getting it "by reference" from the enumdef. */
1307 upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f));
1308 }
1309
1310 /* Ensure that MapEntry submessages only appear as repeated fields, not
1311 * optional/required (singular) fields. */
1312 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
1313 upb_fielddef_msgsubdef(f) != NULL) {
1314 const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
1315 if (upb_msgdef_mapentry(subdef) && !upb_fielddef_isseq(f)) {
1316 upb_status_seterrf(s,
1317 "Field %s refers to mapentry message but is not "
1318 "a repeated field",
1319 upb_fielddef_name(f) ? upb_fielddef_name(f) :
1320 "(unnamed)");
1321 return false;
1322 }
1323 }
1324
1325 return true;
1326}
1327
1328static bool upb_validate_enumdef(const upb_enumdef *e, upb_status *s) {
1329 if (upb_enumdef_numvals(e) == 0) {
1330 upb_status_seterrf(s, "enum %s has no members (must have at least one)",
1331 upb_enumdef_fullname(e));
1332 return false;
1333 }
1334
1335 return true;
1336}
1337
1338/* All submessage fields are lower than all other fields.
1339 * Secondly, fields are increasing in order. */
1340uint32_t field_rank(const upb_fielddef *f) {
1341 uint32_t ret = upb_fielddef_number(f);
1342 const uint32_t high_bit = 1 << 30;
Paul Yange0e54662016-09-15 11:09:01 -07001343 UPB_ASSERT(ret < high_bit);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001344 if (!upb_fielddef_issubmsg(f))
1345 ret |= high_bit;
1346 return ret;
1347}
1348
1349int cmp_fields(const void *p1, const void *p2) {
1350 const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
1351 const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
1352 return field_rank(f1) - field_rank(f2);
1353}
1354
1355static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
1356 /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
1357 * lowest indexes, but we do not publicly guarantee this. */
1358 upb_msg_field_iter j;
Paul Yang5a3405c2017-02-06 12:40:51 -08001359 upb_msg_oneof_iter k;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001360 int i;
1361 uint32_t selector;
1362 int n = upb_msgdef_numfields(m);
Paul Yange0e54662016-09-15 11:09:01 -07001363 upb_fielddef **fields;
1364
1365 if (n == 0) {
1366 m->selector_count = UPB_STATIC_SELECTOR_COUNT;
1367 m->submsg_field_count = 0;
1368 return true;
1369 }
1370
1371 fields = upb_gmalloc(n * sizeof(*fields));
1372 if (!fields) {
1373 upb_upberr_setoom(s);
1374 return false;
1375 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001376
1377 m->submsg_field_count = 0;
1378 for(i = 0, upb_msg_field_begin(&j, m);
1379 !upb_msg_field_done(&j);
1380 upb_msg_field_next(&j), i++) {
1381 upb_fielddef *f = upb_msg_iter_field(&j);
Paul Yange0e54662016-09-15 11:09:01 -07001382 UPB_ASSERT(f->msg.def == m);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001383 if (!upb_validate_field(f, s)) {
Paul Yange0e54662016-09-15 11:09:01 -07001384 upb_gfree(fields);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001385 return false;
1386 }
1387 if (upb_fielddef_issubmsg(f)) {
1388 m->submsg_field_count++;
1389 }
1390 fields[i] = f;
1391 }
1392
1393 qsort(fields, n, sizeof(*fields), cmp_fields);
1394
1395 selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
1396 for (i = 0; i < n; i++) {
1397 upb_fielddef *f = fields[i];
1398 f->index_ = i;
1399 f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
1400 selector += upb_handlers_selectorcount(f);
1401 }
1402 m->selector_count = selector;
1403
1404#ifndef NDEBUG
1405 {
1406 /* Verify that all selectors for the message are distinct. */
1407#define TRY(type) \
1408 if (upb_handlers_getselector(f, type, &sel)) upb_inttable_insert(&t, sel, v);
1409
1410 upb_inttable t;
1411 upb_value v;
1412 upb_selector_t sel;
1413
1414 upb_inttable_init(&t, UPB_CTYPE_BOOL);
1415 v = upb_value_bool(true);
1416 upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
1417 upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
Paul Yang60327462017-10-09 12:39:13 -07001418 upb_inttable_insert(&t, UPB_UNKNOWN_SELECTOR, v);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001419 for(upb_msg_field_begin(&j, m);
1420 !upb_msg_field_done(&j);
1421 upb_msg_field_next(&j)) {
1422 upb_fielddef *f = upb_msg_iter_field(&j);
1423 /* These calls will assert-fail in upb_table if the value already
1424 * exists. */
1425 TRY(UPB_HANDLER_INT32);
1426 TRY(UPB_HANDLER_INT64)
1427 TRY(UPB_HANDLER_UINT32)
1428 TRY(UPB_HANDLER_UINT64)
1429 TRY(UPB_HANDLER_FLOAT)
1430 TRY(UPB_HANDLER_DOUBLE)
1431 TRY(UPB_HANDLER_BOOL)
1432 TRY(UPB_HANDLER_STARTSTR)
1433 TRY(UPB_HANDLER_STRING)
1434 TRY(UPB_HANDLER_ENDSTR)
1435 TRY(UPB_HANDLER_STARTSUBMSG)
1436 TRY(UPB_HANDLER_ENDSUBMSG)
1437 TRY(UPB_HANDLER_STARTSEQ)
1438 TRY(UPB_HANDLER_ENDSEQ)
1439 }
1440 upb_inttable_uninit(&t);
1441 }
1442#undef TRY
1443#endif
1444
Paul Yang5a3405c2017-02-06 12:40:51 -08001445 for(upb_msg_oneof_begin(&k, m), i = 0;
1446 !upb_msg_oneof_done(&k);
1447 upb_msg_oneof_next(&k), i++) {
1448 upb_oneofdef *o = upb_msg_iter_oneof(&k);
1449 o->index = i;
1450 }
1451
Paul Yange0e54662016-09-15 11:09:01 -07001452 upb_gfree(fields);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001453 return true;
1454}
1455
Paul Yang9bda1f12018-09-22 18:57:43 -07001456static void assign_msg_wellknowntype(upb_msgdef *m) {
1457 const char *name = upb_msgdef_fullname(m);
1458 if (name == NULL) {
1459 m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
1460 return;
1461 }
Paul Yang8faa7782018-12-26 10:36:09 -08001462 if (!strcmp(name, "google.protobuf.Any")) {
1463 m->well_known_type = UPB_WELLKNOWN_ANY;
Paul Yangc4f2a922019-01-17 10:18:43 -08001464 } else if (!strcmp(name, "google.protobuf.FieldMask")) {
1465 m->well_known_type = UPB_WELLKNOWN_FIELDMASK;
Paul Yang8faa7782018-12-26 10:36:09 -08001466 } else if (!strcmp(name, "google.protobuf.Duration")) {
Paul Yang9bda1f12018-09-22 18:57:43 -07001467 m->well_known_type = UPB_WELLKNOWN_DURATION;
1468 } else if (!strcmp(name, "google.protobuf.Timestamp")) {
1469 m->well_known_type = UPB_WELLKNOWN_TIMESTAMP;
1470 } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
1471 m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE;
1472 } else if (!strcmp(name, "google.protobuf.FloatValue")) {
1473 m->well_known_type = UPB_WELLKNOWN_FLOATVALUE;
1474 } else if (!strcmp(name, "google.protobuf.Int64Value")) {
1475 m->well_known_type = UPB_WELLKNOWN_INT64VALUE;
1476 } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
1477 m->well_known_type = UPB_WELLKNOWN_UINT64VALUE;
1478 } else if (!strcmp(name, "google.protobuf.Int32Value")) {
1479 m->well_known_type = UPB_WELLKNOWN_INT32VALUE;
1480 } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
1481 m->well_known_type = UPB_WELLKNOWN_UINT32VALUE;
1482 } else if (!strcmp(name, "google.protobuf.BoolValue")) {
1483 m->well_known_type = UPB_WELLKNOWN_BOOLVALUE;
1484 } else if (!strcmp(name, "google.protobuf.StringValue")) {
1485 m->well_known_type = UPB_WELLKNOWN_STRINGVALUE;
1486 } else if (!strcmp(name, "google.protobuf.BytesValue")) {
1487 m->well_known_type = UPB_WELLKNOWN_BYTESVALUE;
1488 } else if (!strcmp(name, "google.protobuf.Value")) {
1489 m->well_known_type = UPB_WELLKNOWN_VALUE;
1490 } else if (!strcmp(name, "google.protobuf.ListValue")) {
1491 m->well_known_type = UPB_WELLKNOWN_LISTVALUE;
1492 } else if (!strcmp(name, "google.protobuf.Struct")) {
1493 m->well_known_type = UPB_WELLKNOWN_STRUCT;
1494 } else {
1495 m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED;
1496 }
1497}
1498
Paul Yange0e54662016-09-15 11:09:01 -07001499bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) {
1500 size_t i;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001501
1502 /* First perform validation, in two passes so we can check that we have a
1503 * transitive closure without needing to search. */
1504 for (i = 0; i < n; i++) {
1505 upb_def *def = defs[i];
1506 if (upb_def_isfrozen(def)) {
1507 /* Could relax this requirement if it's annoying. */
1508 upb_status_seterrmsg(s, "def is already frozen");
1509 goto err;
1510 } else if (def->type == UPB_DEF_FIELD) {
1511 upb_status_seterrmsg(s, "standalone fielddefs can not be frozen");
1512 goto err;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001513 } else {
1514 /* Set now to detect transitive closure in the second pass. */
1515 def->came_from_user = true;
Paul Yang6b27c1f2017-03-17 11:08:06 -07001516
1517 if (def->type == UPB_DEF_ENUM &&
1518 !upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
1519 goto err;
1520 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001521 }
1522 }
1523
1524 /* Second pass of validation. Also assign selector bases and indexes, and
1525 * compact tables. */
1526 for (i = 0; i < n; i++) {
Paul Yange0e54662016-09-15 11:09:01 -07001527 upb_def *def = defs[i];
1528 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
1529 upb_enumdef *e = upb_dyncast_enumdef_mutable(def);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001530 if (m) {
1531 upb_inttable_compact(&m->itof);
1532 if (!assign_msg_indices(m, s)) {
1533 goto err;
1534 }
Paul Yang9bda1f12018-09-22 18:57:43 -07001535 assign_msg_wellknowntype(m);
1536 /* m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001537 } else if (e) {
1538 upb_inttable_compact(&e->iton);
1539 }
1540 }
1541
Paul Yange0e54662016-09-15 11:09:01 -07001542 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001543
1544err:
1545 for (i = 0; i < n; i++) {
Paul Yange0e54662016-09-15 11:09:01 -07001546 upb_def *def = defs[i];
1547 def->came_from_user = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001548 }
Paul Yange0e54662016-09-15 11:09:01 -07001549 UPB_ASSERT(!(s && upb_ok(s)));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001550 return false;
1551}
1552
Paul Yange0e54662016-09-15 11:09:01 -07001553bool upb_def_freeze(upb_def *const* defs, size_t n, upb_status *s) {
1554 /* Def graph contains FieldDefs between each MessageDef, so double the
1555 * limit. */
1556 const size_t maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
1557
1558 if (!_upb_def_validate(defs, n, s)) {
1559 return false;
1560 }
1561
1562
1563 /* Validation all passed; freeze the objects. */
1564 return upb_refcounted_freeze((upb_refcounted *const*)defs, n, s, maxdepth);
1565}
1566
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001567
1568/* upb_enumdef ****************************************************************/
1569
Paul Yange0e54662016-09-15 11:09:01 -07001570static void visitenum(const upb_refcounted *r, upb_refcounted_visit *visit,
1571 void *closure) {
1572 const upb_enumdef *e = (const upb_enumdef*)r;
1573 const upb_def *def = upb_enumdef_upcast(e);
1574 if (upb_def_file(def)) {
1575 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
1576 }
1577}
1578
1579static void freeenum(upb_refcounted *r) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001580 upb_enumdef *e = (upb_enumdef*)r;
1581 upb_inttable_iter i;
1582 upb_inttable_begin(&i, &e->iton);
1583 for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) {
Paul Yange0e54662016-09-15 11:09:01 -07001584 /* To clean up the upb_gstrdup() from upb_enumdef_addval(). */
1585 upb_gfree(upb_value_getcstr(upb_inttable_iter_value(&i)));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001586 }
1587 upb_strtable_uninit(&e->ntoi);
1588 upb_inttable_uninit(&e->iton);
1589 upb_def_uninit(upb_enumdef_upcast_mutable(e));
Paul Yange0e54662016-09-15 11:09:01 -07001590 upb_gfree(e);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001591}
1592
Paul Yange0e54662016-09-15 11:09:01 -07001593const struct upb_refcounted_vtbl upb_enumdef_vtbl = {&visitenum, &freeenum};
1594
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001595upb_enumdef *upb_enumdef_new(const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -07001596 upb_enumdef *e = upb_gmalloc(sizeof(*e));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001597 if (!e) return NULL;
Paul Yange0e54662016-09-15 11:09:01 -07001598
1599 if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM,
1600 &upb_enumdef_vtbl, owner)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001601 goto err2;
Paul Yange0e54662016-09-15 11:09:01 -07001602 }
1603
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001604 if (!upb_strtable_init(&e->ntoi, UPB_CTYPE_INT32)) goto err2;
1605 if (!upb_inttable_init(&e->iton, UPB_CTYPE_CSTR)) goto err1;
1606 return e;
1607
1608err1:
1609 upb_strtable_uninit(&e->ntoi);
1610err2:
Paul Yange0e54662016-09-15 11:09:01 -07001611 upb_gfree(e);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001612 return NULL;
1613}
1614
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001615bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status) {
1616 upb_def *d = upb_enumdef_upcast_mutable(e);
1617 return upb_def_freeze(&d, 1, status);
1618}
1619
1620const char *upb_enumdef_fullname(const upb_enumdef *e) {
1621 return upb_def_fullname(upb_enumdef_upcast(e));
1622}
1623
Paul Yange0e54662016-09-15 11:09:01 -07001624const char *upb_enumdef_name(const upb_enumdef *e) {
1625 return upb_def_name(upb_enumdef_upcast(e));
1626}
1627
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001628bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
1629 upb_status *s) {
1630 return upb_def_setfullname(upb_enumdef_upcast_mutable(e), fullname, s);
1631}
1632
1633bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
1634 upb_status *status) {
Paul Yange0e54662016-09-15 11:09:01 -07001635 char *name2;
1636
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001637 if (!upb_isident(name, strlen(name), false, status)) {
1638 return false;
1639 }
Paul Yange0e54662016-09-15 11:09:01 -07001640
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001641 if (upb_enumdef_ntoiz(e, name, NULL)) {
1642 upb_status_seterrf(status, "name '%s' is already defined", name);
1643 return false;
1644 }
Paul Yange0e54662016-09-15 11:09:01 -07001645
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001646 if (!upb_strtable_insert(&e->ntoi, name, upb_value_int32(num))) {
1647 upb_status_seterrmsg(status, "out of memory");
1648 return false;
1649 }
Paul Yange0e54662016-09-15 11:09:01 -07001650
1651 if (!upb_inttable_lookup(&e->iton, num, NULL)) {
1652 name2 = upb_gstrdup(name);
1653 if (!name2 || !upb_inttable_insert(&e->iton, num, upb_value_cstr(name2))) {
1654 upb_status_seterrmsg(status, "out of memory");
1655 upb_strtable_remove(&e->ntoi, name, NULL);
1656 return false;
1657 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001658 }
Paul Yange0e54662016-09-15 11:09:01 -07001659
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001660 if (upb_enumdef_numvals(e) == 1) {
1661 bool ok = upb_enumdef_setdefault(e, num, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07001662 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001663 }
Paul Yange0e54662016-09-15 11:09:01 -07001664
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001665 return true;
1666}
1667
1668int32_t upb_enumdef_default(const upb_enumdef *e) {
Paul Yange0e54662016-09-15 11:09:01 -07001669 UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001670 return e->defaultval;
1671}
1672
1673bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07001674 UPB_ASSERT(!upb_enumdef_isfrozen(e));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001675 if (!upb_enumdef_iton(e, val)) {
1676 upb_status_seterrf(s, "number '%d' is not in the enum.", val);
1677 return false;
1678 }
1679 e->defaultval = val;
1680 return true;
1681}
1682
1683int upb_enumdef_numvals(const upb_enumdef *e) {
1684 return upb_strtable_count(&e->ntoi);
1685}
1686
1687void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
1688 /* We iterate over the ntoi table, to account for duplicate numbers. */
1689 upb_strtable_begin(i, &e->ntoi);
1690}
1691
1692void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
1693bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
1694
1695bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
1696 size_t len, int32_t *num) {
1697 upb_value v;
1698 if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
1699 return false;
1700 }
1701 if (num) *num = upb_value_getint32(v);
1702 return true;
1703}
1704
1705const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
1706 upb_value v;
1707 return upb_inttable_lookup32(&def->iton, num, &v) ?
1708 upb_value_getcstr(v) : NULL;
1709}
1710
1711const char *upb_enum_iter_name(upb_enum_iter *iter) {
1712 return upb_strtable_iter_key(iter);
1713}
1714
1715int32_t upb_enum_iter_number(upb_enum_iter *iter) {
1716 return upb_value_getint32(upb_strtable_iter_value(iter));
1717}
1718
1719
1720/* upb_fielddef ***************************************************************/
1721
1722static void upb_fielddef_init_default(upb_fielddef *f);
1723
1724static void upb_fielddef_uninit_default(upb_fielddef *f) {
1725 if (f->type_is_set_ && f->default_is_string && f->defaultval.bytes)
1726 freestr(f->defaultval.bytes);
1727}
1728
Paul Yange0e54662016-09-15 11:09:01 -07001729const char *upb_fielddef_fullname(const upb_fielddef *e) {
1730 return upb_def_fullname(upb_fielddef_upcast(e));
1731}
1732
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001733static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
1734 void *closure) {
1735 const upb_fielddef *f = (const upb_fielddef*)r;
Paul Yange0e54662016-09-15 11:09:01 -07001736 const upb_def *def = upb_fielddef_upcast(f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001737 if (upb_fielddef_containingtype(f)) {
1738 visit(r, upb_msgdef_upcast2(upb_fielddef_containingtype(f)), closure);
1739 }
1740 if (upb_fielddef_containingoneof(f)) {
Paul Yange0e54662016-09-15 11:09:01 -07001741 visit(r, upb_oneofdef_upcast(upb_fielddef_containingoneof(f)), closure);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001742 }
1743 if (upb_fielddef_subdef(f)) {
1744 visit(r, upb_def_upcast(upb_fielddef_subdef(f)), closure);
1745 }
Paul Yange0e54662016-09-15 11:09:01 -07001746 if (upb_def_file(def)) {
1747 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
1748 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001749}
1750
1751static void freefield(upb_refcounted *r) {
1752 upb_fielddef *f = (upb_fielddef*)r;
1753 upb_fielddef_uninit_default(f);
1754 if (f->subdef_is_symbolic)
Paul Yange0e54662016-09-15 11:09:01 -07001755 upb_gfree(f->sub.name);
Paul Yang57b65972019-03-19 22:27:13 -07001756 if (f->msg_is_symbolic)
1757 upb_gfree(f->msg.name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001758 upb_def_uninit(upb_fielddef_upcast_mutable(f));
Paul Yange0e54662016-09-15 11:09:01 -07001759 upb_gfree(f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001760}
1761
1762static const char *enumdefaultstr(const upb_fielddef *f) {
1763 const upb_enumdef *e;
Paul Yange0e54662016-09-15 11:09:01 -07001764 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001765 e = upb_fielddef_enumsubdef(f);
1766 if (f->default_is_string && f->defaultval.bytes) {
1767 /* Default was explicitly set as a string. */
1768 str_t *s = f->defaultval.bytes;
1769 return s->str;
1770 } else if (e) {
1771 if (!f->default_is_string) {
1772 /* Default was explicitly set as an integer; look it up in enumdef. */
1773 const char *name = upb_enumdef_iton(e, f->defaultval.sint);
1774 if (name) {
1775 return name;
1776 }
1777 } else {
1778 /* Default is completely unset; pull enumdef default. */
1779 if (upb_enumdef_numvals(e) > 0) {
1780 const char *name = upb_enumdef_iton(e, upb_enumdef_default(e));
Paul Yange0e54662016-09-15 11:09:01 -07001781 UPB_ASSERT(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001782 return name;
1783 }
1784 }
1785 }
1786 return NULL;
1787}
1788
1789static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) {
1790 const upb_enumdef *e;
Paul Yange0e54662016-09-15 11:09:01 -07001791 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001792 e = upb_fielddef_enumsubdef(f);
1793 if (!f->default_is_string) {
1794 /* Default was explicitly set as an integer. */
1795 *val = f->defaultval.sint;
1796 return true;
1797 } else if (e) {
1798 if (f->defaultval.bytes) {
1799 /* Default was explicitly set as a str; try to lookup corresponding int. */
1800 str_t *s = f->defaultval.bytes;
1801 if (upb_enumdef_ntoiz(e, s->str, val)) {
1802 return true;
1803 }
1804 } else {
1805 /* Default is unset; try to pull in enumdef default. */
1806 if (upb_enumdef_numvals(e) > 0) {
1807 *val = upb_enumdef_default(e);
1808 return true;
1809 }
1810 }
1811 }
1812 return false;
1813}
1814
Paul Yange0e54662016-09-15 11:09:01 -07001815const struct upb_refcounted_vtbl upb_fielddef_vtbl = {visitfield, freefield};
1816
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001817upb_fielddef *upb_fielddef_new(const void *o) {
Paul Yange0e54662016-09-15 11:09:01 -07001818 upb_fielddef *f = upb_gmalloc(sizeof(*f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001819 if (!f) return NULL;
Paul Yange0e54662016-09-15 11:09:01 -07001820 if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD,
1821 &upb_fielddef_vtbl, o)) {
1822 upb_gfree(f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001823 return NULL;
1824 }
1825 f->msg.def = NULL;
1826 f->sub.def = NULL;
1827 f->oneof = NULL;
1828 f->subdef_is_symbolic = false;
1829 f->msg_is_symbolic = false;
1830 f->label_ = UPB_LABEL_OPTIONAL;
1831 f->type_ = UPB_TYPE_INT32;
1832 f->number_ = 0;
1833 f->type_is_set_ = false;
1834 f->tagdelim = false;
1835 f->is_extension_ = false;
1836 f->lazy_ = false;
1837 f->packed_ = true;
1838
1839 /* For the moment we default this to UPB_INTFMT_VARIABLE, since it will work
1840 * with all integer types and is in some since more "default" since the most
1841 * normal-looking proto2 types int32/int64/uint32/uint64 use variable.
1842 *
1843 * Other options to consider:
1844 * - there is no default; users must set this manually (like type).
1845 * - default signed integers to UPB_INTFMT_ZIGZAG, since it's more likely to
1846 * be an optimal default for signed integers. */
1847 f->intfmt = UPB_INTFMT_VARIABLE;
1848 return f;
1849}
1850
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001851bool upb_fielddef_typeisset(const upb_fielddef *f) {
1852 return f->type_is_set_;
1853}
1854
1855upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
Paul Yange0e54662016-09-15 11:09:01 -07001856 UPB_ASSERT(f->type_is_set_);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001857 return f->type_;
1858}
1859
1860uint32_t upb_fielddef_index(const upb_fielddef *f) {
1861 return f->index_;
1862}
1863
1864upb_label_t upb_fielddef_label(const upb_fielddef *f) {
1865 return f->label_;
1866}
1867
1868upb_intfmt_t upb_fielddef_intfmt(const upb_fielddef *f) {
1869 return f->intfmt;
1870}
1871
1872bool upb_fielddef_istagdelim(const upb_fielddef *f) {
1873 return f->tagdelim;
1874}
1875
1876uint32_t upb_fielddef_number(const upb_fielddef *f) {
1877 return f->number_;
1878}
1879
1880bool upb_fielddef_isextension(const upb_fielddef *f) {
1881 return f->is_extension_;
1882}
1883
1884bool upb_fielddef_lazy(const upb_fielddef *f) {
1885 return f->lazy_;
1886}
1887
1888bool upb_fielddef_packed(const upb_fielddef *f) {
1889 return f->packed_;
1890}
1891
1892const char *upb_fielddef_name(const upb_fielddef *f) {
1893 return upb_def_fullname(upb_fielddef_upcast(f));
1894}
1895
Paul Yange0e54662016-09-15 11:09:01 -07001896size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
1897 const char *name = upb_fielddef_name(f);
1898 size_t src, dst = 0;
1899 bool ucase_next = false;
1900
1901#define WRITE(byte) \
1902 ++dst; \
1903 if (dst < len) buf[dst - 1] = byte; \
1904 else if (dst == len) buf[dst - 1] = '\0'
1905
1906 if (!name) {
1907 WRITE('\0');
1908 return 0;
1909 }
1910
1911 /* Implement the transformation as described in the spec:
1912 * 1. upper case all letters after an underscore.
1913 * 2. remove all underscores.
1914 */
1915 for (src = 0; name[src]; src++) {
1916 if (name[src] == '_') {
1917 ucase_next = true;
1918 continue;
1919 }
1920
1921 if (ucase_next) {
1922 WRITE(toupper(name[src]));
1923 ucase_next = false;
1924 } else {
1925 WRITE(name[src]);
1926 }
1927 }
1928
1929 WRITE('\0');
1930 return dst;
1931
1932#undef WRITE
1933}
1934
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001935const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
1936 return f->msg_is_symbolic ? NULL : f->msg.def;
1937}
1938
1939const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
1940 return f->oneof;
1941}
1942
1943upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) {
1944 return (upb_msgdef*)upb_fielddef_containingtype(f);
1945}
1946
1947const char *upb_fielddef_containingtypename(upb_fielddef *f) {
1948 return f->msg_is_symbolic ? f->msg.name : NULL;
1949}
1950
1951static void release_containingtype(upb_fielddef *f) {
Paul Yange0e54662016-09-15 11:09:01 -07001952 if (f->msg_is_symbolic) upb_gfree(f->msg.name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001953}
1954
1955bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
1956 upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07001957 char *name_copy;
1958 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001959 if (upb_fielddef_containingtype(f)) {
1960 upb_status_seterrmsg(s, "field has already been added to a message.");
1961 return false;
1962 }
1963 /* TODO: validate name (upb_isident() doesn't quite work atm because this name
1964 * may have a leading "."). */
Paul Yange0e54662016-09-15 11:09:01 -07001965
1966 name_copy = upb_gstrdup(name);
1967 if (!name_copy) {
1968 upb_upberr_setoom(s);
1969 return false;
1970 }
1971
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001972 release_containingtype(f);
Paul Yange0e54662016-09-15 11:09:01 -07001973 f->msg.name = name_copy;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001974 f->msg_is_symbolic = true;
1975 return true;
1976}
1977
1978bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) {
1979 if (upb_fielddef_containingtype(f) || upb_fielddef_containingoneof(f)) {
1980 upb_status_seterrmsg(s, "Already added to message or oneof");
1981 return false;
1982 }
1983 return upb_def_setfullname(upb_fielddef_upcast_mutable(f), name, s);
1984}
1985
1986static void chkdefaulttype(const upb_fielddef *f, upb_fieldtype_t type) {
1987 UPB_UNUSED(f);
1988 UPB_UNUSED(type);
Paul Yange0e54662016-09-15 11:09:01 -07001989 UPB_ASSERT(f->type_is_set_ && upb_fielddef_type(f) == type);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07001990}
1991
1992int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
1993 chkdefaulttype(f, UPB_TYPE_INT64);
1994 return f->defaultval.sint;
1995}
1996
1997int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
1998 if (f->type_is_set_ && upb_fielddef_type(f) == UPB_TYPE_ENUM) {
1999 int32_t val;
2000 bool ok = enumdefaultint32(f, &val);
Paul Yange0e54662016-09-15 11:09:01 -07002001 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002002 return val;
2003 } else {
2004 chkdefaulttype(f, UPB_TYPE_INT32);
2005 return f->defaultval.sint;
2006 }
2007}
2008
2009uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
2010 chkdefaulttype(f, UPB_TYPE_UINT64);
2011 return f->defaultval.uint;
2012}
2013
2014uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
2015 chkdefaulttype(f, UPB_TYPE_UINT32);
2016 return f->defaultval.uint;
2017}
2018
2019bool upb_fielddef_defaultbool(const upb_fielddef *f) {
2020 chkdefaulttype(f, UPB_TYPE_BOOL);
2021 return f->defaultval.uint;
2022}
2023
2024float upb_fielddef_defaultfloat(const upb_fielddef *f) {
2025 chkdefaulttype(f, UPB_TYPE_FLOAT);
2026 return f->defaultval.flt;
2027}
2028
2029double upb_fielddef_defaultdouble(const upb_fielddef *f) {
2030 chkdefaulttype(f, UPB_TYPE_DOUBLE);
2031 return f->defaultval.dbl;
2032}
2033
2034const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
Paul Yange0e54662016-09-15 11:09:01 -07002035 UPB_ASSERT(f->type_is_set_);
2036 UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING ||
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002037 upb_fielddef_type(f) == UPB_TYPE_BYTES ||
2038 upb_fielddef_type(f) == UPB_TYPE_ENUM);
2039
2040 if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
2041 const char *ret = enumdefaultstr(f);
Paul Yange0e54662016-09-15 11:09:01 -07002042 UPB_ASSERT(ret);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002043 /* Enum defaults can't have embedded NULLs. */
2044 if (len) *len = strlen(ret);
2045 return ret;
2046 }
2047
2048 if (f->default_is_string) {
2049 str_t *str = f->defaultval.bytes;
2050 if (len) *len = str->len;
2051 return str->str;
2052 }
2053
2054 return NULL;
2055}
2056
2057static void upb_fielddef_init_default(upb_fielddef *f) {
2058 f->default_is_string = false;
2059 switch (upb_fielddef_type(f)) {
2060 case UPB_TYPE_DOUBLE: f->defaultval.dbl = 0; break;
2061 case UPB_TYPE_FLOAT: f->defaultval.flt = 0; break;
2062 case UPB_TYPE_INT32:
2063 case UPB_TYPE_INT64: f->defaultval.sint = 0; break;
2064 case UPB_TYPE_UINT64:
2065 case UPB_TYPE_UINT32:
2066 case UPB_TYPE_BOOL: f->defaultval.uint = 0; break;
2067 case UPB_TYPE_STRING:
2068 case UPB_TYPE_BYTES:
2069 f->defaultval.bytes = newstr("", 0);
2070 f->default_is_string = true;
2071 break;
2072 case UPB_TYPE_MESSAGE: break;
2073 case UPB_TYPE_ENUM:
2074 /* This is our special sentinel that indicates "not set" for an enum. */
2075 f->default_is_string = true;
2076 f->defaultval.bytes = NULL;
2077 break;
2078 }
2079}
2080
2081const upb_def *upb_fielddef_subdef(const upb_fielddef *f) {
2082 return f->subdef_is_symbolic ? NULL : f->sub.def;
2083}
2084
2085const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
2086 const upb_def *def = upb_fielddef_subdef(f);
2087 return def ? upb_dyncast_msgdef(def) : NULL;
2088}
2089
2090const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
2091 const upb_def *def = upb_fielddef_subdef(f);
2092 return def ? upb_dyncast_enumdef(def) : NULL;
2093}
2094
2095upb_def *upb_fielddef_subdef_mutable(upb_fielddef *f) {
2096 return (upb_def*)upb_fielddef_subdef(f);
2097}
2098
2099const char *upb_fielddef_subdefname(const upb_fielddef *f) {
2100 if (f->subdef_is_symbolic) {
2101 return f->sub.name;
2102 } else if (f->sub.def) {
2103 return upb_def_fullname(f->sub.def);
2104 } else {
2105 return NULL;
2106 }
2107}
2108
2109bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
2110 if (upb_fielddef_containingtype(f)) {
2111 upb_status_seterrmsg(
2112 s, "cannot change field number after adding to a message");
2113 return false;
2114 }
Paul Yang57b65972019-03-19 22:27:13 -07002115 if (number == 0) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002116 upb_status_seterrf(s, "invalid field number (%u)", number);
2117 return false;
2118 }
2119 f->number_ = number;
2120 return true;
2121}
2122
2123void upb_fielddef_settype(upb_fielddef *f, upb_fieldtype_t type) {
Paul Yange0e54662016-09-15 11:09:01 -07002124 UPB_ASSERT(!upb_fielddef_isfrozen(f));
2125 UPB_ASSERT(upb_fielddef_checktype(type));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002126 upb_fielddef_uninit_default(f);
2127 f->type_ = type;
2128 f->type_is_set_ = true;
2129 upb_fielddef_init_default(f);
2130}
2131
2132void upb_fielddef_setdescriptortype(upb_fielddef *f, int type) {
Paul Yange0e54662016-09-15 11:09:01 -07002133 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002134 switch (type) {
2135 case UPB_DESCRIPTOR_TYPE_DOUBLE:
2136 upb_fielddef_settype(f, UPB_TYPE_DOUBLE);
2137 break;
2138 case UPB_DESCRIPTOR_TYPE_FLOAT:
2139 upb_fielddef_settype(f, UPB_TYPE_FLOAT);
2140 break;
2141 case UPB_DESCRIPTOR_TYPE_INT64:
2142 case UPB_DESCRIPTOR_TYPE_SFIXED64:
2143 case UPB_DESCRIPTOR_TYPE_SINT64:
2144 upb_fielddef_settype(f, UPB_TYPE_INT64);
2145 break;
2146 case UPB_DESCRIPTOR_TYPE_UINT64:
2147 case UPB_DESCRIPTOR_TYPE_FIXED64:
2148 upb_fielddef_settype(f, UPB_TYPE_UINT64);
2149 break;
2150 case UPB_DESCRIPTOR_TYPE_INT32:
2151 case UPB_DESCRIPTOR_TYPE_SFIXED32:
2152 case UPB_DESCRIPTOR_TYPE_SINT32:
2153 upb_fielddef_settype(f, UPB_TYPE_INT32);
2154 break;
2155 case UPB_DESCRIPTOR_TYPE_UINT32:
2156 case UPB_DESCRIPTOR_TYPE_FIXED32:
2157 upb_fielddef_settype(f, UPB_TYPE_UINT32);
2158 break;
2159 case UPB_DESCRIPTOR_TYPE_BOOL:
2160 upb_fielddef_settype(f, UPB_TYPE_BOOL);
2161 break;
2162 case UPB_DESCRIPTOR_TYPE_STRING:
2163 upb_fielddef_settype(f, UPB_TYPE_STRING);
2164 break;
2165 case UPB_DESCRIPTOR_TYPE_BYTES:
2166 upb_fielddef_settype(f, UPB_TYPE_BYTES);
2167 break;
2168 case UPB_DESCRIPTOR_TYPE_GROUP:
2169 case UPB_DESCRIPTOR_TYPE_MESSAGE:
2170 upb_fielddef_settype(f, UPB_TYPE_MESSAGE);
2171 break;
2172 case UPB_DESCRIPTOR_TYPE_ENUM:
2173 upb_fielddef_settype(f, UPB_TYPE_ENUM);
2174 break;
Paul Yange0e54662016-09-15 11:09:01 -07002175 default: UPB_ASSERT(false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002176 }
2177
2178 if (type == UPB_DESCRIPTOR_TYPE_FIXED64 ||
2179 type == UPB_DESCRIPTOR_TYPE_FIXED32 ||
2180 type == UPB_DESCRIPTOR_TYPE_SFIXED64 ||
2181 type == UPB_DESCRIPTOR_TYPE_SFIXED32) {
2182 upb_fielddef_setintfmt(f, UPB_INTFMT_FIXED);
2183 } else if (type == UPB_DESCRIPTOR_TYPE_SINT64 ||
2184 type == UPB_DESCRIPTOR_TYPE_SINT32) {
2185 upb_fielddef_setintfmt(f, UPB_INTFMT_ZIGZAG);
2186 } else {
2187 upb_fielddef_setintfmt(f, UPB_INTFMT_VARIABLE);
2188 }
2189
2190 upb_fielddef_settagdelim(f, type == UPB_DESCRIPTOR_TYPE_GROUP);
2191}
2192
2193upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
2194 switch (upb_fielddef_type(f)) {
2195 case UPB_TYPE_FLOAT: return UPB_DESCRIPTOR_TYPE_FLOAT;
2196 case UPB_TYPE_DOUBLE: return UPB_DESCRIPTOR_TYPE_DOUBLE;
2197 case UPB_TYPE_BOOL: return UPB_DESCRIPTOR_TYPE_BOOL;
2198 case UPB_TYPE_STRING: return UPB_DESCRIPTOR_TYPE_STRING;
2199 case UPB_TYPE_BYTES: return UPB_DESCRIPTOR_TYPE_BYTES;
2200 case UPB_TYPE_ENUM: return UPB_DESCRIPTOR_TYPE_ENUM;
2201 case UPB_TYPE_INT32:
2202 switch (upb_fielddef_intfmt(f)) {
2203 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT32;
2204 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED32;
2205 case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT32;
2206 }
2207 case UPB_TYPE_INT64:
2208 switch (upb_fielddef_intfmt(f)) {
2209 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT64;
2210 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED64;
2211 case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT64;
2212 }
2213 case UPB_TYPE_UINT32:
2214 switch (upb_fielddef_intfmt(f)) {
2215 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT32;
2216 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED32;
2217 case UPB_INTFMT_ZIGZAG: return -1;
2218 }
2219 case UPB_TYPE_UINT64:
2220 switch (upb_fielddef_intfmt(f)) {
2221 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT64;
2222 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED64;
2223 case UPB_INTFMT_ZIGZAG: return -1;
2224 }
2225 case UPB_TYPE_MESSAGE:
2226 return upb_fielddef_istagdelim(f) ?
2227 UPB_DESCRIPTOR_TYPE_GROUP : UPB_DESCRIPTOR_TYPE_MESSAGE;
2228 }
2229 return 0;
2230}
2231
2232void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension) {
Paul Yange0e54662016-09-15 11:09:01 -07002233 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002234 f->is_extension_ = is_extension;
2235}
2236
2237void upb_fielddef_setlazy(upb_fielddef *f, bool lazy) {
Paul Yange0e54662016-09-15 11:09:01 -07002238 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002239 f->lazy_ = lazy;
2240}
2241
2242void upb_fielddef_setpacked(upb_fielddef *f, bool packed) {
Paul Yange0e54662016-09-15 11:09:01 -07002243 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002244 f->packed_ = packed;
2245}
2246
2247void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label) {
Paul Yange0e54662016-09-15 11:09:01 -07002248 UPB_ASSERT(!upb_fielddef_isfrozen(f));
2249 UPB_ASSERT(upb_fielddef_checklabel(label));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002250 f->label_ = label;
2251}
2252
2253void upb_fielddef_setintfmt(upb_fielddef *f, upb_intfmt_t fmt) {
Paul Yange0e54662016-09-15 11:09:01 -07002254 UPB_ASSERT(!upb_fielddef_isfrozen(f));
2255 UPB_ASSERT(upb_fielddef_checkintfmt(fmt));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002256 f->intfmt = fmt;
2257}
2258
2259void upb_fielddef_settagdelim(upb_fielddef *f, bool tag_delim) {
Paul Yange0e54662016-09-15 11:09:01 -07002260 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002261 f->tagdelim = tag_delim;
2262 f->tagdelim = tag_delim;
2263}
2264
2265static bool checksetdefault(upb_fielddef *f, upb_fieldtype_t type) {
2266 if (!f->type_is_set_ || upb_fielddef_isfrozen(f) ||
2267 upb_fielddef_type(f) != type) {
Paul Yange0e54662016-09-15 11:09:01 -07002268 UPB_ASSERT(false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002269 return false;
2270 }
2271 if (f->default_is_string) {
2272 str_t *s = f->defaultval.bytes;
Paul Yange0e54662016-09-15 11:09:01 -07002273 UPB_ASSERT(s || type == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002274 if (s) freestr(s);
2275 }
2276 f->default_is_string = false;
2277 return true;
2278}
2279
2280void upb_fielddef_setdefaultint64(upb_fielddef *f, int64_t value) {
2281 if (checksetdefault(f, UPB_TYPE_INT64))
2282 f->defaultval.sint = value;
2283}
2284
2285void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t value) {
2286 if ((upb_fielddef_type(f) == UPB_TYPE_ENUM &&
2287 checksetdefault(f, UPB_TYPE_ENUM)) ||
2288 checksetdefault(f, UPB_TYPE_INT32)) {
2289 f->defaultval.sint = value;
2290 }
2291}
2292
2293void upb_fielddef_setdefaultuint64(upb_fielddef *f, uint64_t value) {
2294 if (checksetdefault(f, UPB_TYPE_UINT64))
2295 f->defaultval.uint = value;
2296}
2297
2298void upb_fielddef_setdefaultuint32(upb_fielddef *f, uint32_t value) {
2299 if (checksetdefault(f, UPB_TYPE_UINT32))
2300 f->defaultval.uint = value;
2301}
2302
2303void upb_fielddef_setdefaultbool(upb_fielddef *f, bool value) {
2304 if (checksetdefault(f, UPB_TYPE_BOOL))
2305 f->defaultval.uint = value;
2306}
2307
2308void upb_fielddef_setdefaultfloat(upb_fielddef *f, float value) {
2309 if (checksetdefault(f, UPB_TYPE_FLOAT))
2310 f->defaultval.flt = value;
2311}
2312
2313void upb_fielddef_setdefaultdouble(upb_fielddef *f, double value) {
2314 if (checksetdefault(f, UPB_TYPE_DOUBLE))
2315 f->defaultval.dbl = value;
2316}
2317
2318bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
2319 upb_status *s) {
2320 str_t *str2;
Paul Yange0e54662016-09-15 11:09:01 -07002321 UPB_ASSERT(upb_fielddef_isstring(f) || f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002322 if (f->type_ == UPB_TYPE_ENUM && !upb_isident(str, len, false, s))
2323 return false;
2324
2325 if (f->default_is_string) {
2326 str_t *s = f->defaultval.bytes;
Paul Yange0e54662016-09-15 11:09:01 -07002327 UPB_ASSERT(s || f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002328 if (s) freestr(s);
2329 } else {
Paul Yange0e54662016-09-15 11:09:01 -07002330 UPB_ASSERT(f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002331 }
2332
2333 str2 = newstr(str, len);
2334 f->defaultval.bytes = str2;
2335 f->default_is_string = true;
2336 return true;
2337}
2338
2339void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
2340 upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07002341 UPB_ASSERT(f->type_is_set_);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002342 upb_fielddef_setdefaultstr(f, str, str ? strlen(str) : 0, s);
2343}
2344
2345bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f) {
2346 int32_t val;
Paul Yange0e54662016-09-15 11:09:01 -07002347 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002348 return enumdefaultint32(f, &val);
2349}
2350
2351bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f) {
Paul Yange0e54662016-09-15 11:09:01 -07002352 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002353 return enumdefaultstr(f) != NULL;
2354}
2355
2356static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
2357 upb_status *s) {
2358 if (f->type_ == UPB_TYPE_MESSAGE) {
2359 if (upb_dyncast_msgdef(subdef)) return true;
2360 upb_status_seterrmsg(s, "invalid subdef type for this submessage field");
2361 return false;
2362 } else if (f->type_ == UPB_TYPE_ENUM) {
2363 if (upb_dyncast_enumdef(subdef)) return true;
2364 upb_status_seterrmsg(s, "invalid subdef type for this enum field");
2365 return false;
2366 } else {
2367 upb_status_seterrmsg(s, "only message and enum fields can have a subdef");
2368 return false;
2369 }
2370}
2371
2372static void release_subdef(upb_fielddef *f) {
2373 if (f->subdef_is_symbolic) {
Paul Yange0e54662016-09-15 11:09:01 -07002374 upb_gfree(f->sub.name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002375 } else if (f->sub.def) {
2376 upb_unref2(f->sub.def, f);
2377 }
2378}
2379
2380bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef,
2381 upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07002382 UPB_ASSERT(!upb_fielddef_isfrozen(f));
2383 UPB_ASSERT(upb_fielddef_hassubdef(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002384 if (subdef && !upb_subdef_typecheck(f, subdef, s)) return false;
2385 release_subdef(f);
2386 f->sub.def = subdef;
2387 f->subdef_is_symbolic = false;
2388 if (f->sub.def) upb_ref2(f->sub.def, f);
2389 return true;
2390}
2391
2392bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef,
2393 upb_status *s) {
2394 return upb_fielddef_setsubdef(f, upb_msgdef_upcast(subdef), s);
2395}
2396
2397bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef,
2398 upb_status *s) {
2399 return upb_fielddef_setsubdef(f, upb_enumdef_upcast(subdef), s);
2400}
2401
2402bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name,
2403 upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07002404 char *name_copy;
2405 UPB_ASSERT(!upb_fielddef_isfrozen(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002406 if (!upb_fielddef_hassubdef(f)) {
2407 upb_status_seterrmsg(s, "field type does not accept a subdef");
2408 return false;
2409 }
Paul Yange0e54662016-09-15 11:09:01 -07002410
2411 name_copy = upb_gstrdup(name);
2412 if (!name_copy) {
2413 upb_upberr_setoom(s);
2414 return false;
2415 }
2416
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002417 /* TODO: validate name (upb_isident() doesn't quite work atm because this name
2418 * may have a leading "."). */
2419 release_subdef(f);
Paul Yange0e54662016-09-15 11:09:01 -07002420 f->sub.name = name_copy;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002421 f->subdef_is_symbolic = true;
2422 return true;
2423}
2424
2425bool upb_fielddef_issubmsg(const upb_fielddef *f) {
2426 return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
2427}
2428
2429bool upb_fielddef_isstring(const upb_fielddef *f) {
2430 return upb_fielddef_type(f) == UPB_TYPE_STRING ||
2431 upb_fielddef_type(f) == UPB_TYPE_BYTES;
2432}
2433
2434bool upb_fielddef_isseq(const upb_fielddef *f) {
2435 return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
2436}
2437
2438bool upb_fielddef_isprimitive(const upb_fielddef *f) {
2439 return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
2440}
2441
2442bool upb_fielddef_ismap(const upb_fielddef *f) {
2443 return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
2444 upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
2445}
2446
Paul Yange0e54662016-09-15 11:09:01 -07002447bool upb_fielddef_haspresence(const upb_fielddef *f) {
2448 if (upb_fielddef_isseq(f)) return false;
2449 if (upb_fielddef_issubmsg(f)) return true;
2450
2451 /* Primitive field: return true unless there is a message that specifies
2452 * presence should not exist. */
2453 if (f->msg_is_symbolic || !f->msg.def) return true;
2454 return f->msg.def->syntax == UPB_SYNTAX_PROTO2;
2455}
2456
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002457bool upb_fielddef_hassubdef(const upb_fielddef *f) {
2458 return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
2459}
2460
2461static bool between(int32_t x, int32_t low, int32_t high) {
2462 return x >= low && x <= high;
2463}
2464
2465bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
2466bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
2467bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
2468
2469bool upb_fielddef_checkdescriptortype(int32_t type) {
2470 return between(type, 1, 18);
2471}
2472
2473/* upb_msgdef *****************************************************************/
2474
2475static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit,
2476 void *closure) {
2477 upb_msg_oneof_iter o;
2478 const upb_msgdef *m = (const upb_msgdef*)r;
Paul Yange0e54662016-09-15 11:09:01 -07002479 const upb_def *def = upb_msgdef_upcast(m);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002480 upb_msg_field_iter i;
2481 for(upb_msg_field_begin(&i, m);
2482 !upb_msg_field_done(&i);
2483 upb_msg_field_next(&i)) {
2484 upb_fielddef *f = upb_msg_iter_field(&i);
2485 visit(r, upb_fielddef_upcast2(f), closure);
2486 }
2487 for(upb_msg_oneof_begin(&o, m);
2488 !upb_msg_oneof_done(&o);
2489 upb_msg_oneof_next(&o)) {
2490 upb_oneofdef *f = upb_msg_iter_oneof(&o);
Paul Yange0e54662016-09-15 11:09:01 -07002491 visit(r, upb_oneofdef_upcast(f), closure);
2492 }
2493 if (upb_def_file(def)) {
2494 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002495 }
2496}
2497
2498static void freemsg(upb_refcounted *r) {
2499 upb_msgdef *m = (upb_msgdef*)r;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002500 upb_strtable_uninit(&m->ntof);
2501 upb_inttable_uninit(&m->itof);
2502 upb_def_uninit(upb_msgdef_upcast_mutable(m));
Paul Yange0e54662016-09-15 11:09:01 -07002503 upb_gfree(m);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002504}
2505
Paul Yange0e54662016-09-15 11:09:01 -07002506const struct upb_refcounted_vtbl upb_msgdef_vtbl = {visitmsg, freemsg};
2507
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002508upb_msgdef *upb_msgdef_new(const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -07002509 upb_msgdef *m = upb_gmalloc(sizeof(*m));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002510 if (!m) return NULL;
Paul Yange0e54662016-09-15 11:09:01 -07002511
2512 if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &upb_msgdef_vtbl,
2513 owner)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002514 goto err2;
Paul Yange0e54662016-09-15 11:09:01 -07002515 }
2516
2517 if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err2;
2518 if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err1;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002519 m->map_entry = false;
Paul Yange0e54662016-09-15 11:09:01 -07002520 m->syntax = UPB_SYNTAX_PROTO2;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002521 return m;
2522
2523err1:
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002524 upb_inttable_uninit(&m->itof);
Paul Yange0e54662016-09-15 11:09:01 -07002525err2:
2526 upb_gfree(m);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002527 return NULL;
2528}
2529
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002530bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) {
2531 upb_def *d = upb_msgdef_upcast_mutable(m);
2532 return upb_def_freeze(&d, 1, status);
2533}
2534
2535const char *upb_msgdef_fullname(const upb_msgdef *m) {
2536 return upb_def_fullname(upb_msgdef_upcast(m));
2537}
2538
Paul Yange0e54662016-09-15 11:09:01 -07002539const char *upb_msgdef_name(const upb_msgdef *m) {
2540 return upb_def_name(upb_msgdef_upcast(m));
2541}
2542
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002543bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
2544 upb_status *s) {
2545 return upb_def_setfullname(upb_msgdef_upcast_mutable(m), fullname, s);
2546}
2547
Paul Yange0e54662016-09-15 11:09:01 -07002548bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax) {
2549 if (syntax != UPB_SYNTAX_PROTO2 && syntax != UPB_SYNTAX_PROTO3) {
2550 return false;
2551 }
2552
2553 m->syntax = syntax;
2554 return true;
2555}
2556
2557upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
2558 return m->syntax;
2559}
2560
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002561/* Helper: check that the field |f| is safe to add to msgdef |m|. Set an error
2562 * on status |s| and return false if not. */
2563static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
2564 upb_status *s) {
2565 if (upb_fielddef_containingtype(f) != NULL) {
2566 upb_status_seterrmsg(s, "fielddef already belongs to a message");
2567 return false;
2568 } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
2569 upb_status_seterrmsg(s, "field name or number were not set");
2570 return false;
Paul Yange0e54662016-09-15 11:09:01 -07002571 } else if (upb_msgdef_itof(m, upb_fielddef_number(f))) {
2572 upb_status_seterrmsg(s, "duplicate field number");
2573 return false;
2574 } else if (upb_strtable_lookup(&m->ntof, upb_fielddef_name(f), NULL)) {
2575 upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002576 return false;
2577 }
2578 return true;
2579}
2580
2581static void add_field(upb_msgdef *m, upb_fielddef *f, const void *ref_donor) {
2582 release_containingtype(f);
2583 f->msg.def = m;
2584 f->msg_is_symbolic = false;
2585 upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
2586 upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
2587 upb_ref2(f, m);
2588 upb_ref2(m, f);
2589 if (ref_donor) upb_fielddef_unref(f, ref_donor);
2590}
2591
2592bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
2593 upb_status *s) {
2594 /* TODO: extensions need to have a separate namespace, because proto2 allows a
2595 * top-level extension (ie. one not in any package) to have the same name as a
2596 * field from the message.
2597 *
2598 * This also implies that there needs to be a separate lookup-by-name method
2599 * for extensions. It seems desirable for iteration to return both extensions
2600 * and non-extensions though.
2601 *
2602 * We also need to validate that the field number is in an extension range iff
2603 * it is an extension.
2604 *
2605 * This method is idempotent. Check if |f| is already part of this msgdef and
2606 * return immediately if so. */
2607 if (upb_fielddef_containingtype(f) == m) {
Paul Yange0e54662016-09-15 11:09:01 -07002608 if (ref_donor) upb_fielddef_unref(f, ref_donor);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002609 return true;
2610 }
2611
2612 /* Check constraints for all fields before performing any action. */
2613 if (!check_field_add(m, f, s)) {
2614 return false;
2615 } else if (upb_fielddef_containingoneof(f) != NULL) {
2616 /* Fields in a oneof can only be added by adding the oneof to the msgdef. */
2617 upb_status_seterrmsg(s, "fielddef is part of a oneof");
2618 return false;
2619 }
2620
2621 /* Constraint checks ok, perform the action. */
2622 add_field(m, f, ref_donor);
2623 return true;
2624}
2625
2626bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
2627 upb_status *s) {
2628 upb_oneof_iter it;
2629
2630 /* Check various conditions that would prevent this oneof from being added. */
2631 if (upb_oneofdef_containingtype(o)) {
2632 upb_status_seterrmsg(s, "oneofdef already belongs to a message");
2633 return false;
2634 } else if (upb_oneofdef_name(o) == NULL) {
2635 upb_status_seterrmsg(s, "oneofdef name was not set");
2636 return false;
Paul Yange0e54662016-09-15 11:09:01 -07002637 } else if (upb_strtable_lookup(&m->ntof, upb_oneofdef_name(o), NULL)) {
2638 upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002639 return false;
2640 }
2641
2642 /* Check that all of the oneof's fields do not conflict with names or numbers
2643 * of fields already in the message. */
2644 for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
2645 const upb_fielddef *f = upb_oneof_iter_field(&it);
2646 if (!check_field_add(m, f, s)) {
2647 return false;
2648 }
2649 }
2650
2651 /* Everything checks out -- commit now. */
2652
2653 /* Add oneof itself first. */
2654 o->parent = m;
Paul Yange0e54662016-09-15 11:09:01 -07002655 upb_strtable_insert(&m->ntof, upb_oneofdef_name(o), upb_value_ptr(o));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002656 upb_ref2(o, m);
2657 upb_ref2(m, o);
2658
2659 /* Add each field of the oneof directly to the msgdef. */
2660 for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
2661 upb_fielddef *f = upb_oneof_iter_field(&it);
2662 add_field(m, f, NULL);
2663 }
2664
2665 if (ref_donor) upb_oneofdef_unref(o, ref_donor);
2666
2667 return true;
2668}
2669
2670const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
2671 upb_value val;
2672 return upb_inttable_lookup32(&m->itof, i, &val) ?
2673 upb_value_getptr(val) : NULL;
2674}
2675
2676const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
2677 size_t len) {
2678 upb_value val;
Paul Yange0e54662016-09-15 11:09:01 -07002679
2680 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
2681 return NULL;
2682 }
2683
2684 return upb_trygetfield(upb_value_getptr(val));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002685}
2686
2687const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
2688 size_t len) {
2689 upb_value val;
Paul Yange0e54662016-09-15 11:09:01 -07002690
2691 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
2692 return NULL;
2693 }
2694
2695 return upb_trygetoneof(upb_value_getptr(val));
2696}
2697
2698bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
2699 const upb_fielddef **f, const upb_oneofdef **o) {
2700 upb_value val;
2701
2702 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
2703 return false;
2704 }
2705
2706 *o = upb_trygetoneof(upb_value_getptr(val));
2707 *f = upb_trygetfield(upb_value_getptr(val));
2708 UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */
2709 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002710}
2711
2712int upb_msgdef_numfields(const upb_msgdef *m) {
Paul Yange0e54662016-09-15 11:09:01 -07002713 /* The number table contains only fields. */
2714 return upb_inttable_count(&m->itof);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002715}
2716
2717int upb_msgdef_numoneofs(const upb_msgdef *m) {
Paul Yange0e54662016-09-15 11:09:01 -07002718 /* The name table includes oneofs, and the number table does not. */
2719 return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002720}
2721
2722void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) {
Paul Yange0e54662016-09-15 11:09:01 -07002723 UPB_ASSERT(!upb_msgdef_isfrozen(m));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002724 m->map_entry = map_entry;
2725}
2726
2727bool upb_msgdef_mapentry(const upb_msgdef *m) {
2728 return m->map_entry;
2729}
2730
Paul Yang9bda1f12018-09-22 18:57:43 -07002731upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) {
2732 return m->well_known_type;
2733}
2734
2735bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) {
2736 upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
2737 return type >= UPB_WELLKNOWN_DOUBLEVALUE &&
2738 type <= UPB_WELLKNOWN_UINT32VALUE;
2739}
2740
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002741void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
2742 upb_inttable_begin(iter, &m->itof);
2743}
2744
2745void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
2746
2747bool upb_msg_field_done(const upb_msg_field_iter *iter) {
2748 return upb_inttable_done(iter);
2749}
2750
2751upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
2752 return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
2753}
2754
2755void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
2756 upb_inttable_iter_setdone(iter);
2757}
2758
2759void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
Paul Yange0e54662016-09-15 11:09:01 -07002760 upb_strtable_begin(iter, &m->ntof);
2761 /* We need to skip past any initial fields. */
2762 while (!upb_strtable_done(iter) &&
2763 !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter)))) {
2764 upb_strtable_next(iter);
2765 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002766}
2767
Paul Yange0e54662016-09-15 11:09:01 -07002768void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
2769 /* We need to skip past fields to return only oneofs. */
2770 do {
2771 upb_strtable_next(iter);
2772 } while (!upb_strtable_done(iter) &&
2773 !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter))));
2774}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002775
2776bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
2777 return upb_strtable_done(iter);
2778}
2779
2780upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
2781 return (upb_oneofdef*)upb_value_getptr(upb_strtable_iter_value(iter));
2782}
2783
2784void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
2785 upb_strtable_iter_setdone(iter);
2786}
2787
2788/* upb_oneofdef ***************************************************************/
2789
2790static void visitoneof(const upb_refcounted *r, upb_refcounted_visit *visit,
2791 void *closure) {
2792 const upb_oneofdef *o = (const upb_oneofdef*)r;
2793 upb_oneof_iter i;
2794 for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
2795 const upb_fielddef *f = upb_oneof_iter_field(&i);
2796 visit(r, upb_fielddef_upcast2(f), closure);
2797 }
2798 if (o->parent) {
2799 visit(r, upb_msgdef_upcast2(o->parent), closure);
2800 }
2801}
2802
2803static void freeoneof(upb_refcounted *r) {
2804 upb_oneofdef *o = (upb_oneofdef*)r;
2805 upb_strtable_uninit(&o->ntof);
2806 upb_inttable_uninit(&o->itof);
Paul Yange0e54662016-09-15 11:09:01 -07002807 upb_gfree((void*)o->name);
2808 upb_gfree(o);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002809}
2810
Paul Yange0e54662016-09-15 11:09:01 -07002811const struct upb_refcounted_vtbl upb_oneofdef_vtbl = {visitoneof, freeoneof};
2812
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002813upb_oneofdef *upb_oneofdef_new(const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -07002814 upb_oneofdef *o = upb_gmalloc(sizeof(*o));
2815
2816 if (!o) {
2817 return NULL;
2818 }
2819
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002820 o->parent = NULL;
Paul Yange0e54662016-09-15 11:09:01 -07002821 o->name = NULL;
2822
2823 if (!upb_refcounted_init(upb_oneofdef_upcast_mutable(o), &upb_oneofdef_vtbl,
2824 owner)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002825 goto err2;
Paul Yange0e54662016-09-15 11:09:01 -07002826 }
2827
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002828 if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2;
2829 if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1;
Paul Yange0e54662016-09-15 11:09:01 -07002830
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002831 return o;
2832
2833err1:
2834 upb_inttable_uninit(&o->itof);
2835err2:
Paul Yange0e54662016-09-15 11:09:01 -07002836 upb_gfree(o);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002837 return NULL;
2838}
2839
Paul Yange0e54662016-09-15 11:09:01 -07002840const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002841
Paul Yange0e54662016-09-15 11:09:01 -07002842bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) {
2843 UPB_ASSERT(!upb_oneofdef_isfrozen(o));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002844 if (upb_oneofdef_containingtype(o)) {
2845 upb_status_seterrmsg(s, "oneof already added to a message");
2846 return false;
2847 }
Paul Yange0e54662016-09-15 11:09:01 -07002848
2849 if (!upb_isident(name, strlen(name), true, s)) {
2850 return false;
2851 }
2852
2853 name = upb_gstrdup(name);
2854 if (!name) {
2855 upb_status_seterrmsg(s, "One of memory");
2856 return false;
2857 }
2858
2859 upb_gfree((void*)o->name);
2860 o->name = name;
2861 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002862}
2863
2864const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
2865 return o->parent;
2866}
2867
2868int upb_oneofdef_numfields(const upb_oneofdef *o) {
2869 return upb_strtable_count(&o->ntof);
2870}
2871
Paul Yang5a3405c2017-02-06 12:40:51 -08002872uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
2873 return o->index;
2874}
2875
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002876bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f,
2877 const void *ref_donor,
2878 upb_status *s) {
Paul Yange0e54662016-09-15 11:09:01 -07002879 UPB_ASSERT(!upb_oneofdef_isfrozen(o));
2880 UPB_ASSERT(!o->parent || !upb_msgdef_isfrozen(o->parent));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002881
2882 /* This method is idempotent. Check if |f| is already part of this oneofdef
2883 * and return immediately if so. */
2884 if (upb_fielddef_containingoneof(f) == o) {
2885 return true;
2886 }
2887
2888 /* The field must have an OPTIONAL label. */
2889 if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
2890 upb_status_seterrmsg(s, "fields in oneof must have OPTIONAL label");
2891 return false;
2892 }
2893
2894 /* Check that no field with this name or number exists already in the oneof.
2895 * Also check that the field is not already part of a oneof. */
2896 if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
2897 upb_status_seterrmsg(s, "field name or number were not set");
2898 return false;
2899 } else if (upb_oneofdef_itof(o, upb_fielddef_number(f)) ||
2900 upb_oneofdef_ntofz(o, upb_fielddef_name(f))) {
2901 upb_status_seterrmsg(s, "duplicate field name or number");
2902 return false;
2903 } else if (upb_fielddef_containingoneof(f) != NULL) {
2904 upb_status_seterrmsg(s, "fielddef already belongs to a oneof");
2905 return false;
2906 }
2907
2908 /* We allow adding a field to the oneof either if the field is not part of a
2909 * msgdef, or if it is and we are also part of the same msgdef. */
2910 if (o->parent == NULL) {
2911 /* If we're not in a msgdef, the field cannot be either. Otherwise we would
2912 * need to magically add this oneof to a msgdef to remain consistent, which
2913 * is surprising behavior. */
2914 if (upb_fielddef_containingtype(f) != NULL) {
2915 upb_status_seterrmsg(s, "fielddef already belongs to a message, but "
2916 "oneof does not");
2917 return false;
2918 }
2919 } else {
2920 /* If we're in a msgdef, the user can add fields that either aren't in any
2921 * msgdef (in which case they're added to our msgdef) or already a part of
2922 * our msgdef. */
2923 if (upb_fielddef_containingtype(f) != NULL &&
2924 upb_fielddef_containingtype(f) != o->parent) {
2925 upb_status_seterrmsg(s, "fielddef belongs to a different message "
2926 "than oneof");
2927 return false;
2928 }
2929 }
2930
2931 /* Commit phase. First add the field to our parent msgdef, if any, because
2932 * that may fail; then add the field to our own tables. */
2933
2934 if (o->parent != NULL && upb_fielddef_containingtype(f) == NULL) {
2935 if (!upb_msgdef_addfield((upb_msgdef*)o->parent, f, NULL, s)) {
2936 return false;
2937 }
2938 }
2939
2940 release_containingtype(f);
2941 f->oneof = o;
2942 upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f));
2943 upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f));
2944 upb_ref2(f, o);
2945 upb_ref2(o, f);
2946 if (ref_donor) upb_fielddef_unref(f, ref_donor);
2947
2948 return true;
2949}
2950
2951const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
2952 const char *name, size_t length) {
2953 upb_value val;
2954 return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
2955 upb_value_getptr(val) : NULL;
2956}
2957
2958const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
2959 upb_value val;
2960 return upb_inttable_lookup32(&o->itof, num, &val) ?
2961 upb_value_getptr(val) : NULL;
2962}
2963
2964void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
2965 upb_inttable_begin(iter, &o->itof);
2966}
2967
2968void upb_oneof_next(upb_oneof_iter *iter) {
2969 upb_inttable_next(iter);
2970}
2971
2972bool upb_oneof_done(upb_oneof_iter *iter) {
2973 return upb_inttable_done(iter);
2974}
2975
2976upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
2977 return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
2978}
2979
2980void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
2981 upb_inttable_iter_setdone(iter);
2982}
2983
Paul Yange0e54662016-09-15 11:09:01 -07002984/* upb_filedef ****************************************************************/
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002985
Paul Yange0e54662016-09-15 11:09:01 -07002986static void visitfiledef(const upb_refcounted *r, upb_refcounted_visit *visit,
2987 void *closure) {
2988 const upb_filedef *f = (const upb_filedef*)r;
2989 size_t i;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002990
Paul Yange0e54662016-09-15 11:09:01 -07002991 for(i = 0; i < upb_filedef_defcount(f); i++) {
2992 visit(r, upb_def_upcast(upb_filedef_def(f, i)), closure);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002993 }
Paul Yange0e54662016-09-15 11:09:01 -07002994}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002995
Paul Yange0e54662016-09-15 11:09:01 -07002996static void freefiledef(upb_refcounted *r) {
2997 upb_filedef *f = (upb_filedef*)r;
2998 size_t i;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07002999
Paul Yange0e54662016-09-15 11:09:01 -07003000 for(i = 0; i < upb_filedef_depcount(f); i++) {
3001 upb_filedef_unref(upb_filedef_dep(f, i), f);
3002 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003003
Paul Yange0e54662016-09-15 11:09:01 -07003004 upb_inttable_uninit(&f->defs);
3005 upb_inttable_uninit(&f->deps);
3006 upb_gfree((void*)f->name);
3007 upb_gfree((void*)f->package);
Paul Yang6b27c1f2017-03-17 11:08:06 -07003008 upb_gfree((void*)f->phpprefix);
Paul Yang6f325802017-06-05 00:10:18 -07003009 upb_gfree((void*)f->phpnamespace);
Paul Yange0e54662016-09-15 11:09:01 -07003010 upb_gfree(f);
3011}
3012
3013const struct upb_refcounted_vtbl upb_filedef_vtbl = {visitfiledef, freefiledef};
3014
3015upb_filedef *upb_filedef_new(const void *owner) {
3016 upb_filedef *f = upb_gmalloc(sizeof(*f));
3017
3018 if (!f) {
3019 return NULL;
3020 }
3021
3022 f->package = NULL;
3023 f->name = NULL;
Paul Yang6b27c1f2017-03-17 11:08:06 -07003024 f->phpprefix = NULL;
Paul Yang6f325802017-06-05 00:10:18 -07003025 f->phpnamespace = NULL;
Paul Yange0e54662016-09-15 11:09:01 -07003026 f->syntax = UPB_SYNTAX_PROTO2;
3027
3028 if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl,
3029 owner)) {
3030 goto err;
3031 }
3032
3033 if (!upb_inttable_init(&f->defs, UPB_CTYPE_CONSTPTR)) {
3034 goto err;
3035 }
3036
3037 if (!upb_inttable_init(&f->deps, UPB_CTYPE_CONSTPTR)) {
3038 goto err2;
3039 }
3040
3041 return f;
3042
3043
3044err2:
3045 upb_inttable_uninit(&f->defs);
3046
3047err:
3048 upb_gfree(f);
3049 return NULL;
3050}
3051
3052const char *upb_filedef_name(const upb_filedef *f) {
3053 return f->name;
3054}
3055
3056const char *upb_filedef_package(const upb_filedef *f) {
3057 return f->package;
3058}
3059
Paul Yang6b27c1f2017-03-17 11:08:06 -07003060const char *upb_filedef_phpprefix(const upb_filedef *f) {
3061 return f->phpprefix;
3062}
3063
Paul Yang6f325802017-06-05 00:10:18 -07003064const char *upb_filedef_phpnamespace(const upb_filedef *f) {
3065 return f->phpnamespace;
3066}
3067
Paul Yange0e54662016-09-15 11:09:01 -07003068upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
3069 return f->syntax;
3070}
3071
3072size_t upb_filedef_defcount(const upb_filedef *f) {
3073 return upb_inttable_count(&f->defs);
3074}
3075
3076size_t upb_filedef_depcount(const upb_filedef *f) {
3077 return upb_inttable_count(&f->deps);
3078}
3079
3080const upb_def *upb_filedef_def(const upb_filedef *f, size_t i) {
3081 upb_value v;
3082
3083 if (upb_inttable_lookup32(&f->defs, i, &v)) {
3084 return upb_value_getconstptr(v);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003085 } else {
Paul Yange0e54662016-09-15 11:09:01 -07003086 return NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003087 }
3088}
3089
Paul Yange0e54662016-09-15 11:09:01 -07003090const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i) {
3091 upb_value v;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003092
Paul Yange0e54662016-09-15 11:09:01 -07003093 if (upb_inttable_lookup32(&f->deps, i, &v)) {
3094 return upb_value_getconstptr(v);
3095 } else {
3096 return NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003097 }
3098}
3099
Paul Yange0e54662016-09-15 11:09:01 -07003100bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s) {
3101 name = upb_gstrdup(name);
3102 if (!name) {
3103 upb_upberr_setoom(s);
3104 return false;
3105 }
3106 upb_gfree((void*)f->name);
3107 f->name = name;
3108 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003109}
3110
Paul Yange0e54662016-09-15 11:09:01 -07003111bool upb_filedef_setpackage(upb_filedef *f, const char *package,
3112 upb_status *s) {
3113 if (!upb_isident(package, strlen(package), true, s)) return false;
3114 package = upb_gstrdup(package);
3115 if (!package) {
3116 upb_upberr_setoom(s);
3117 return false;
3118 }
3119 upb_gfree((void*)f->package);
3120 f->package = package;
3121 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003122}
3123
Paul Yang6b27c1f2017-03-17 11:08:06 -07003124bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix,
3125 upb_status *s) {
3126 phpprefix = upb_gstrdup(phpprefix);
3127 if (!phpprefix) {
3128 upb_upberr_setoom(s);
3129 return false;
3130 }
3131 upb_gfree((void*)f->phpprefix);
3132 f->phpprefix = phpprefix;
3133 return true;
3134}
3135
Paul Yang6f325802017-06-05 00:10:18 -07003136bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
3137 upb_status *s) {
3138 phpnamespace = upb_gstrdup(phpnamespace);
3139 if (!phpnamespace) {
3140 upb_upberr_setoom(s);
3141 return false;
3142 }
3143 upb_gfree((void*)f->phpnamespace);
3144 f->phpnamespace = phpnamespace;
3145 return true;
3146}
3147
Paul Yange0e54662016-09-15 11:09:01 -07003148bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax,
3149 upb_status *s) {
3150 UPB_UNUSED(s);
3151 if (syntax != UPB_SYNTAX_PROTO2 &&
3152 syntax != UPB_SYNTAX_PROTO3) {
3153 upb_status_seterrmsg(s, "Unknown syntax value.");
3154 return false;
3155 }
3156 f->syntax = syntax;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003157
Paul Yange0e54662016-09-15 11:09:01 -07003158 {
3159 /* Set all messages in this file to match. */
3160 size_t i;
3161 for (i = 0; i < upb_filedef_defcount(f); i++) {
3162 /* Casting const away is safe since all defs in mutable filedef must
3163 * also be mutable. */
3164 upb_def *def = (upb_def*)upb_filedef_def(f, i);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003165
Paul Yange0e54662016-09-15 11:09:01 -07003166 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
3167 if (m) {
3168 m->syntax = syntax;
3169 }
3170 }
3171 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003172
3173 return true;
3174}
3175
Paul Yange0e54662016-09-15 11:09:01 -07003176bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
3177 upb_status *s) {
3178 if (def->file) {
3179 upb_status_seterrmsg(s, "Def is already part of another filedef.");
3180 return false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003181 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003182
Paul Yange0e54662016-09-15 11:09:01 -07003183 if (upb_inttable_push(&f->defs, upb_value_constptr(def))) {
3184 def->file = f;
3185 upb_ref2(def, f);
3186 upb_ref2(f, def);
3187 if (ref_donor) upb_def_unref(def, ref_donor);
3188 if (def->type == UPB_DEF_MSG) {
3189 upb_downcast_msgdef_mutable(def)->syntax = f->syntax;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003190 }
Paul Yange0e54662016-09-15 11:09:01 -07003191 return true;
3192 } else {
3193 upb_upberr_setoom(s);
3194 return false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003195 }
3196}
3197
Paul Yange0e54662016-09-15 11:09:01 -07003198bool upb_filedef_adddep(upb_filedef *f, const upb_filedef *dep) {
3199 if (upb_inttable_push(&f->deps, upb_value_constptr(dep))) {
3200 /* Regular ref instead of ref2 because files can't form cycles. */
3201 upb_filedef_ref(dep, f);
3202 return true;
3203 } else {
3204 return false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003205 }
3206}
Paul Yang5a3405c2017-02-06 12:40:51 -08003207
3208void upb_symtab_free(upb_symtab *s) {
3209 upb_strtable_iter i;
3210 upb_strtable_begin(&i, &s->symtab);
3211 for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
3212 const upb_def *def = upb_value_getptr(upb_strtable_iter_value(&i));
3213 upb_def_unref(def, s);
3214 }
3215 upb_strtable_uninit(&s->symtab);
3216 upb_gfree(s);
3217}
3218
3219upb_symtab *upb_symtab_new() {
3220 upb_symtab *s = upb_gmalloc(sizeof(*s));
3221 if (!s) {
3222 return NULL;
3223 }
3224
3225 upb_strtable_init(&s->symtab, UPB_CTYPE_PTR);
3226 return s;
3227}
3228
3229const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
3230 upb_value v;
3231 upb_def *ret = upb_strtable_lookup(&s->symtab, sym, &v) ?
3232 upb_value_getptr(v) : NULL;
3233 return ret;
3234}
3235
3236const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
3237 upb_value v;
3238 upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
3239 upb_value_getptr(v) : NULL;
3240 return def ? upb_dyncast_msgdef(def) : NULL;
3241}
3242
Paul Yang8faa7782018-12-26 10:36:09 -08003243const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
3244 size_t len) {
3245 upb_value v;
3246 upb_def *def = upb_strtable_lookup2(&s->symtab, sym, len, &v) ?
3247 upb_value_getptr(v) : NULL;
3248 return def ? upb_dyncast_msgdef(def) : NULL;
3249}
3250
Paul Yang5a3405c2017-02-06 12:40:51 -08003251const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
3252 upb_value v;
3253 upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
3254 upb_value_getptr(v) : NULL;
3255 return def ? upb_dyncast_enumdef(def) : NULL;
3256}
3257
3258/* Given a symbol and the base symbol inside which it is defined, find the
3259 * symbol's definition in t. */
3260static upb_def *upb_resolvename(const upb_strtable *t,
3261 const char *base, const char *sym) {
3262 if(strlen(sym) == 0) return NULL;
3263 if(sym[0] == '.') {
3264 /* Symbols starting with '.' are absolute, so we do a single lookup.
3265 * Slice to omit the leading '.' */
3266 upb_value v;
3267 return upb_strtable_lookup(t, sym + 1, &v) ? upb_value_getptr(v) : NULL;
3268 } else {
3269 /* Remove components from base until we find an entry or run out.
3270 * TODO: This branch is totally broken, but currently not used. */
3271 (void)base;
3272 UPB_ASSERT(false);
3273 return NULL;
3274 }
3275}
3276
3277const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
3278 const char *sym) {
3279 upb_def *ret = upb_resolvename(&s->symtab, base, sym);
3280 return ret;
3281}
3282
3283/* TODO(haberman): we need a lot more testing of error conditions. */
3284static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
3285 void *ref_donor, upb_refcounted *freeze_also,
3286 upb_status *status) {
3287 size_t i;
3288 size_t add_n;
3289 size_t freeze_n;
3290 upb_strtable_iter iter;
3291 upb_refcounted **add_objs = NULL;
3292 upb_def **add_defs = NULL;
3293 size_t add_objs_size;
3294 upb_strtable addtab;
3295
3296 if (n == 0 && !freeze_also) {
3297 return true;
3298 }
3299
3300 if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
3301 upb_status_seterrmsg(status, "out of memory");
3302 return false;
3303 }
3304
3305 /* Add new defs to our "add" set. */
3306 for (i = 0; i < n; i++) {
3307 upb_def *def = defs[i];
3308 const char *fullname;
3309 upb_fielddef *f;
3310
3311 if (upb_def_isfrozen(def)) {
3312 upb_status_seterrmsg(status, "added defs must be mutable");
3313 goto err;
3314 }
3315 UPB_ASSERT(!upb_def_isfrozen(def));
3316 fullname = upb_def_fullname(def);
3317 if (!fullname) {
3318 upb_status_seterrmsg(
3319 status, "Anonymous defs cannot be added to a symtab");
3320 goto err;
3321 }
3322
3323 f = upb_dyncast_fielddef_mutable(def);
3324
3325 if (f) {
3326 if (!upb_fielddef_containingtypename(f)) {
3327 upb_status_seterrmsg(status,
3328 "Standalone fielddefs must have a containing type "
3329 "(extendee) name set");
3330 goto err;
3331 }
3332 } else {
3333 if (upb_strtable_lookup(&addtab, fullname, NULL)) {
3334 upb_status_seterrf(status, "Conflicting defs named '%s'", fullname);
3335 goto err;
3336 }
3337 if (upb_strtable_lookup(&s->symtab, fullname, NULL)) {
3338 upb_status_seterrf(status, "Symtab already has a def named '%s'",
3339 fullname);
3340 goto err;
3341 }
Paul Yang5a3405c2017-02-06 12:40:51 -08003342 if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def)))
3343 goto oom_err;
Paul Yang6b27c1f2017-03-17 11:08:06 -07003344 upb_def_donateref(def, ref_donor, s);
Paul Yang5a3405c2017-02-06 12:40:51 -08003345 }
3346
Paul Yang6b27c1f2017-03-17 11:08:06 -07003347 if (upb_dyncast_fielddef_mutable(def)) {
3348 /* TODO(haberman): allow adding extensions attached to files. */
3349 upb_status_seterrf(status, "Can't add extensions to symtab.\n");
Paul Yang5a3405c2017-02-06 12:40:51 -08003350 goto err;
3351 }
3352 }
3353
3354 /* Now using the table, resolve symbolic references for subdefs. */
3355 upb_strtable_begin(&iter, &addtab);
3356 for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
3357 const char *base;
3358 upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
3359 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
3360 upb_msg_field_iter j;
3361
3362 if (!m) continue;
3363 /* Type names are resolved relative to the message in which they appear. */
3364 base = upb_msgdef_fullname(m);
3365
3366 for(upb_msg_field_begin(&j, m);
3367 !upb_msg_field_done(&j);
3368 upb_msg_field_next(&j)) {
3369 upb_fielddef *f = upb_msg_iter_field(&j);
3370 const char *name = upb_fielddef_subdefname(f);
3371 if (name && !upb_fielddef_subdef(f)) {
3372 /* Try the lookup in the current set of to-be-added defs first. If not
3373 * there, try existing defs. */
3374 upb_def *subdef = upb_resolvename(&addtab, base, name);
3375 if (subdef == NULL) {
3376 subdef = upb_resolvename(&s->symtab, base, name);
3377 }
3378 if (subdef == NULL) {
3379 upb_status_seterrf(
3380 status, "couldn't resolve name '%s' in message '%s'", name, base);
3381 goto err;
3382 } else if (!upb_fielddef_setsubdef(f, subdef, status)) {
3383 goto err;
3384 }
3385 }
3386 }
3387 }
3388
3389 /* We need an array of the defs in addtab, for passing to
3390 * upb_refcounted_freeze(). */
3391 add_objs_size = upb_strtable_count(&addtab);
3392 if (freeze_also) {
3393 add_objs_size++;
3394 }
3395
3396 add_defs = upb_gmalloc(sizeof(void*) * add_objs_size);
3397 if (add_defs == NULL) goto oom_err;
3398 upb_strtable_begin(&iter, &addtab);
3399 for (add_n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
3400 add_defs[add_n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
3401 }
3402
3403 /* Validate defs. */
3404 if (!_upb_def_validate(add_defs, add_n, status)) {
3405 goto err;
3406 }
3407
3408 /* Cheat a little and give the array a new type.
3409 * This is probably undefined behavior, but this code will be deleted soon. */
3410 add_objs = (upb_refcounted**)add_defs;
3411
3412 freeze_n = add_n;
3413 if (freeze_also) {
3414 add_objs[freeze_n++] = freeze_also;
3415 }
3416
3417 if (!upb_refcounted_freeze(add_objs, freeze_n, status,
3418 UPB_MAX_MESSAGE_DEPTH * 2)) {
3419 goto err;
3420 }
3421
3422 /* This must be delayed until all errors have been detected, since error
3423 * recovery code uses this table to cleanup defs. */
3424 upb_strtable_uninit(&addtab);
3425
3426 /* TODO(haberman) we don't properly handle errors after this point (like
3427 * OOM in upb_strtable_insert() below). */
3428 for (i = 0; i < add_n; i++) {
3429 upb_def *def = (upb_def*)add_objs[i];
3430 const char *name = upb_def_fullname(def);
Paul Yang5a3405c2017-02-06 12:40:51 -08003431 bool success;
Paul Yang5a3405c2017-02-06 12:40:51 -08003432 success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
Paul Yang6b27c1f2017-03-17 11:08:06 -07003433 UPB_ASSERT(success);
Paul Yang5a3405c2017-02-06 12:40:51 -08003434 }
3435 upb_gfree(add_defs);
3436 return true;
3437
3438oom_err:
3439 upb_status_seterrmsg(status, "out of memory");
3440err: {
3441 /* We need to donate the refs back. */
3442 upb_strtable_begin(&iter, &addtab);
3443 for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
3444 upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
3445 upb_def_donateref(def, s, ref_donor);
3446 }
3447 }
3448 upb_strtable_uninit(&addtab);
3449 upb_gfree(add_defs);
3450 UPB_ASSERT(!upb_ok(status));
3451 return false;
3452}
3453
3454bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
3455 void *ref_donor, upb_status *status) {
3456 return symtab_add(s, defs, n, ref_donor, NULL, status);
3457}
3458
3459bool upb_symtab_addfile(upb_symtab *s, upb_filedef *file, upb_status *status) {
3460 size_t n;
3461 size_t i;
3462 upb_def **defs;
3463 bool ret;
3464
3465 n = upb_filedef_defcount(file);
Paul Yangecca6ea2017-06-30 12:14:09 -07003466 if (n == 0) {
3467 return true;
3468 }
Paul Yang5a3405c2017-02-06 12:40:51 -08003469 defs = upb_gmalloc(sizeof(*defs) * n);
3470
3471 if (defs == NULL) {
3472 upb_status_seterrmsg(status, "Out of memory");
3473 return false;
3474 }
3475
3476 for (i = 0; i < n; i++) {
3477 defs[i] = upb_filedef_mutabledef(file, i);
3478 }
3479
3480 ret = symtab_add(s, defs, n, NULL, upb_filedef_upcast_mutable(file), status);
3481
3482 upb_gfree(defs);
3483 return ret;
3484}
3485
3486/* Iteration. */
3487
3488static void advance_to_matching(upb_symtab_iter *iter) {
3489 if (iter->type == UPB_DEF_ANY)
3490 return;
3491
3492 while (!upb_strtable_done(&iter->iter) &&
3493 iter->type != upb_symtab_iter_def(iter)->type) {
3494 upb_strtable_next(&iter->iter);
3495 }
3496}
3497
3498void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
3499 upb_deftype_t type) {
3500 upb_strtable_begin(&iter->iter, &s->symtab);
3501 iter->type = type;
3502 advance_to_matching(iter);
3503}
3504
3505void upb_symtab_next(upb_symtab_iter *iter) {
3506 upb_strtable_next(&iter->iter);
3507 advance_to_matching(iter);
3508}
3509
3510bool upb_symtab_done(const upb_symtab_iter *iter) {
3511 return upb_strtable_done(&iter->iter);
3512}
3513
3514const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
3515 return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
3516}
Paul Yang60327462017-10-09 12:39:13 -07003517/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
3518
3519
3520#define UPB_PB_VARINT_MAX_LEN 10
3521#define CHK(x) do { if (!(x)) { return false; } } while(0)
3522
3523/* Maps descriptor type -> upb field type. */
3524static const uint8_t upb_desctype_to_fieldtype2[] = {
3525 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
3526 UPB_TYPE_DOUBLE, /* DOUBLE */
3527 UPB_TYPE_FLOAT, /* FLOAT */
3528 UPB_TYPE_INT64, /* INT64 */
3529 UPB_TYPE_UINT64, /* UINT64 */
3530 UPB_TYPE_INT32, /* INT32 */
3531 UPB_TYPE_UINT64, /* FIXED64 */
3532 UPB_TYPE_UINT32, /* FIXED32 */
3533 UPB_TYPE_BOOL, /* BOOL */
3534 UPB_TYPE_STRING, /* STRING */
3535 UPB_TYPE_MESSAGE, /* GROUP */
3536 UPB_TYPE_MESSAGE, /* MESSAGE */
3537 UPB_TYPE_BYTES, /* BYTES */
3538 UPB_TYPE_UINT32, /* UINT32 */
3539 UPB_TYPE_ENUM, /* ENUM */
3540 UPB_TYPE_INT32, /* SFIXED32 */
3541 UPB_TYPE_INT64, /* SFIXED64 */
3542 UPB_TYPE_INT32, /* SINT32 */
3543 UPB_TYPE_INT64, /* SINT64 */
3544};
3545
3546static size_t upb_encode_varint(uint64_t val, char *buf) {
3547 size_t i;
3548 if (val < 128) { buf[0] = val; return 1; }
3549 i = 0;
3550 while (val) {
3551 uint8_t byte = val & 0x7fU;
3552 val >>= 7;
3553 if (val) byte |= 0x80U;
3554 buf[i++] = byte;
3555 }
3556 return i;
3557}
3558
3559static uint32_t upb_zzencode_32(int32_t n) { return (n << 1) ^ (n >> 31); }
3560static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
3561
3562typedef struct {
Paul Yang9bda1f12018-09-22 18:57:43 -07003563 upb_alloc *alloc;
Paul Yang60327462017-10-09 12:39:13 -07003564 char *buf, *ptr, *limit;
3565} upb_encstate;
3566
3567static size_t upb_roundup_pow2(size_t bytes) {
3568 size_t ret = 128;
3569 while (ret < bytes) {
3570 ret *= 2;
3571 }
3572 return ret;
3573}
3574
3575static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
3576 size_t old_size = e->limit - e->buf;
3577 size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
Paul Yang9bda1f12018-09-22 18:57:43 -07003578 char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
Paul Yang60327462017-10-09 12:39:13 -07003579 CHK(new_buf);
3580
3581 /* We want previous data at the end, realloc() put it at the beginning. */
Paul Yang6dd563a2018-03-08 17:35:22 -08003582 memmove(new_buf + new_size - old_size, e->buf, old_size);
Paul Yang60327462017-10-09 12:39:13 -07003583
3584 e->ptr = new_buf + new_size - (e->limit - e->ptr);
3585 e->limit = new_buf + new_size;
3586 e->buf = new_buf;
3587 return true;
3588}
3589
3590/* Call to ensure that at least "bytes" bytes are available for writing at
3591 * e->ptr. Returns false if the bytes could not be allocated. */
3592static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
3593 CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
3594 upb_encode_growbuffer(e, bytes));
3595
3596 e->ptr -= bytes;
3597 return true;
3598}
3599
3600/* Writes the given bytes to the buffer, handling reserve/advance. */
3601static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
3602 CHK(upb_encode_reserve(e, len));
3603 memcpy(e->ptr, data, len);
3604 return true;
3605}
3606
3607static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
3608 /* TODO(haberman): byte-swap for big endian. */
3609 return upb_put_bytes(e, &val, sizeof(uint64_t));
3610}
3611
3612static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
3613 /* TODO(haberman): byte-swap for big endian. */
3614 return upb_put_bytes(e, &val, sizeof(uint32_t));
3615}
3616
3617static bool upb_put_varint(upb_encstate *e, uint64_t val) {
3618 size_t len;
3619 char *start;
3620 CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
3621 len = upb_encode_varint(val, e->ptr);
3622 start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
3623 memmove(start, e->ptr, len);
3624 e->ptr = start;
3625 return true;
3626}
3627
3628static bool upb_put_double(upb_encstate *e, double d) {
3629 uint64_t u64;
3630 UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
3631 memcpy(&u64, &d, sizeof(uint64_t));
3632 return upb_put_fixed64(e, u64);
3633}
3634
3635static bool upb_put_float(upb_encstate *e, float d) {
3636 uint32_t u32;
3637 UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
3638 memcpy(&u32, &d, sizeof(uint32_t));
3639 return upb_put_fixed32(e, u32);
3640}
3641
Paul Yang9bda1f12018-09-22 18:57:43 -07003642static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) {
Paul Yang60327462017-10-09 12:39:13 -07003643 uint32_t ret;
Paul Yang9bda1f12018-09-22 18:57:43 -07003644 uint32_t offset = ~f->presence;
3645 memcpy(&ret, msg + offset, sizeof(ret));
Paul Yang60327462017-10-09 12:39:13 -07003646 return ret;
3647}
3648
Paul Yang9bda1f12018-09-22 18:57:43 -07003649static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) {
3650 uint32_t hasbit = f->presence;
3651 UPB_ASSERT(f->presence > 0);
3652 return msg[hasbit / 8] & (1 << (hasbit % 8));
Paul Yang60327462017-10-09 12:39:13 -07003653}
3654
3655static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
3656 return upb_put_varint(e, (field_number << 3) | wire_type);
3657}
3658
3659static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
3660 size_t size) {
3661 size_t bytes = arr->len * size;
3662 return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
3663}
3664
3665bool upb_encode_message(upb_encstate *e, const char *msg,
Paul Yang9bda1f12018-09-22 18:57:43 -07003666 const upb_msglayout *m, size_t *size);
Paul Yang60327462017-10-09 12:39:13 -07003667
3668static bool upb_encode_array(upb_encstate *e, const char *field_mem,
Paul Yang9bda1f12018-09-22 18:57:43 -07003669 const upb_msglayout *m,
3670 const upb_msglayout_field *f) {
Paul Yang60327462017-10-09 12:39:13 -07003671 const upb_array *arr = *(const upb_array**)field_mem;
3672
3673 if (arr == NULL || arr->len == 0) {
3674 return true;
3675 }
3676
Paul Yang0f4ad852018-03-06 13:30:03 -08003677 UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->descriptortype]);
Paul Yang60327462017-10-09 12:39:13 -07003678
3679#define VARINT_CASE(ctype, encode) { \
3680 ctype *start = arr->data; \
3681 ctype *ptr = start + arr->len; \
3682 size_t pre_len = e->limit - e->ptr; \
3683 do { \
3684 ptr--; \
3685 CHK(upb_put_varint(e, encode)); \
3686 } while (ptr != start); \
3687 CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
3688} \
3689break; \
3690do { ; } while(0)
3691
Paul Yang0f4ad852018-03-06 13:30:03 -08003692 switch (f->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -07003693 case UPB_DESCRIPTOR_TYPE_DOUBLE:
3694 CHK(upb_put_fixedarray(e, arr, sizeof(double)));
3695 break;
3696 case UPB_DESCRIPTOR_TYPE_FLOAT:
3697 CHK(upb_put_fixedarray(e, arr, sizeof(float)));
3698 break;
3699 case UPB_DESCRIPTOR_TYPE_SFIXED64:
3700 case UPB_DESCRIPTOR_TYPE_FIXED64:
3701 CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
3702 break;
3703 case UPB_DESCRIPTOR_TYPE_FIXED32:
3704 case UPB_DESCRIPTOR_TYPE_SFIXED32:
3705 CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
3706 break;
3707 case UPB_DESCRIPTOR_TYPE_INT64:
3708 case UPB_DESCRIPTOR_TYPE_UINT64:
3709 VARINT_CASE(uint64_t, *ptr);
3710 case UPB_DESCRIPTOR_TYPE_UINT32:
Paul Yang6dd563a2018-03-08 17:35:22 -08003711 VARINT_CASE(uint32_t, *ptr);
Paul Yang60327462017-10-09 12:39:13 -07003712 case UPB_DESCRIPTOR_TYPE_INT32:
3713 case UPB_DESCRIPTOR_TYPE_ENUM:
Paul Yang6dd563a2018-03-08 17:35:22 -08003714 VARINT_CASE(int32_t, (int64_t)*ptr);
Paul Yang60327462017-10-09 12:39:13 -07003715 case UPB_DESCRIPTOR_TYPE_BOOL:
3716 VARINT_CASE(bool, *ptr);
3717 case UPB_DESCRIPTOR_TYPE_SINT32:
3718 VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
3719 case UPB_DESCRIPTOR_TYPE_SINT64:
3720 VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
3721 case UPB_DESCRIPTOR_TYPE_STRING:
3722 case UPB_DESCRIPTOR_TYPE_BYTES: {
Paul Yang57b65972019-03-19 22:27:13 -07003723 upb_strview *start = arr->data;
3724 upb_strview *ptr = start + arr->len;
Paul Yang60327462017-10-09 12:39:13 -07003725 do {
3726 ptr--;
3727 CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
3728 upb_put_varint(e, ptr->size) &&
3729 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3730 } while (ptr != start);
3731 return true;
3732 }
3733 case UPB_DESCRIPTOR_TYPE_GROUP: {
3734 void **start = arr->data;
3735 void **ptr = start + arr->len;
Paul Yang9bda1f12018-09-22 18:57:43 -07003736 const upb_msglayout *subm = m->submsgs[f->submsg_index];
Paul Yang60327462017-10-09 12:39:13 -07003737 do {
3738 size_t size;
3739 ptr--;
3740 CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
3741 upb_encode_message(e, *ptr, subm, &size) &&
3742 upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
3743 } while (ptr != start);
3744 return true;
3745 }
3746 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
3747 void **start = arr->data;
3748 void **ptr = start + arr->len;
Paul Yang9bda1f12018-09-22 18:57:43 -07003749 const upb_msglayout *subm = m->submsgs[f->submsg_index];
Paul Yang60327462017-10-09 12:39:13 -07003750 do {
3751 size_t size;
3752 ptr--;
3753 CHK(upb_encode_message(e, *ptr, subm, &size) &&
3754 upb_put_varint(e, size) &&
3755 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3756 } while (ptr != start);
3757 return true;
3758 }
3759 }
3760#undef VARINT_CASE
3761
3762 /* We encode all primitive arrays as packed, regardless of what was specified
3763 * in the .proto file. Could special case 1-sized arrays. */
3764 CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
3765 return true;
3766}
3767
3768static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
Paul Yang9bda1f12018-09-22 18:57:43 -07003769 const upb_msglayout *m,
3770 const upb_msglayout_field *f,
3771 bool skip_zero_value) {
Paul Yang60327462017-10-09 12:39:13 -07003772#define CASE(ctype, type, wire_type, encodeval) do { \
3773 ctype val = *(ctype*)field_mem; \
3774 if (skip_zero_value && val == 0) { \
3775 return true; \
3776 } \
3777 return upb_put_ ## type(e, encodeval) && \
3778 upb_put_tag(e, f->number, wire_type); \
3779} while(0)
3780
Paul Yang0f4ad852018-03-06 13:30:03 -08003781 switch (f->descriptortype) {
Paul Yang60327462017-10-09 12:39:13 -07003782 case UPB_DESCRIPTOR_TYPE_DOUBLE:
3783 CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
3784 case UPB_DESCRIPTOR_TYPE_FLOAT:
3785 CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
3786 case UPB_DESCRIPTOR_TYPE_INT64:
3787 case UPB_DESCRIPTOR_TYPE_UINT64:
3788 CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
3789 case UPB_DESCRIPTOR_TYPE_UINT32:
Paul Yang6dd563a2018-03-08 17:35:22 -08003790 CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
Paul Yang60327462017-10-09 12:39:13 -07003791 case UPB_DESCRIPTOR_TYPE_INT32:
3792 case UPB_DESCRIPTOR_TYPE_ENUM:
Paul Yang6dd563a2018-03-08 17:35:22 -08003793 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
Paul Yang60327462017-10-09 12:39:13 -07003794 case UPB_DESCRIPTOR_TYPE_SFIXED64:
3795 case UPB_DESCRIPTOR_TYPE_FIXED64:
3796 CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
3797 case UPB_DESCRIPTOR_TYPE_FIXED32:
3798 case UPB_DESCRIPTOR_TYPE_SFIXED32:
3799 CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
3800 case UPB_DESCRIPTOR_TYPE_BOOL:
3801 CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
3802 case UPB_DESCRIPTOR_TYPE_SINT32:
3803 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
3804 case UPB_DESCRIPTOR_TYPE_SINT64:
3805 CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
3806 case UPB_DESCRIPTOR_TYPE_STRING:
3807 case UPB_DESCRIPTOR_TYPE_BYTES: {
Paul Yang57b65972019-03-19 22:27:13 -07003808 upb_strview view = *(upb_strview*)field_mem;
Paul Yang60327462017-10-09 12:39:13 -07003809 if (skip_zero_value && view.size == 0) {
3810 return true;
3811 }
3812 return upb_put_bytes(e, view.data, view.size) &&
3813 upb_put_varint(e, view.size) &&
3814 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
3815 }
3816 case UPB_DESCRIPTOR_TYPE_GROUP: {
3817 size_t size;
Paul Yang9bda1f12018-09-22 18:57:43 -07003818 void *submsg = *(void **)field_mem;
3819 const upb_msglayout *subm = m->submsgs[f->submsg_index];
3820 if (submsg == NULL) {
Paul Yang60327462017-10-09 12:39:13 -07003821 return true;
3822 }
3823 return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
3824 upb_encode_message(e, submsg, subm, &size) &&
3825 upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
3826 }
3827 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
3828 size_t size;
Paul Yang9bda1f12018-09-22 18:57:43 -07003829 void *submsg = *(void **)field_mem;
3830 const upb_msglayout *subm = m->submsgs[f->submsg_index];
3831 if (submsg == NULL) {
Paul Yang60327462017-10-09 12:39:13 -07003832 return true;
3833 }
3834 return upb_encode_message(e, submsg, subm, &size) &&
3835 upb_put_varint(e, size) &&
3836 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
3837 }
3838 }
3839#undef CASE
3840 UPB_UNREACHABLE();
3841}
3842
Paul Yang9bda1f12018-09-22 18:57:43 -07003843bool upb_encode_message(upb_encstate *e, const char *msg,
3844 const upb_msglayout *m, size_t *size) {
Paul Yang60327462017-10-09 12:39:13 -07003845 int i;
Paul Yang6dd563a2018-03-08 17:35:22 -08003846 size_t pre_len = e->limit - e->ptr;
Paul Yang9bda1f12018-09-22 18:57:43 -07003847 const char *unknown;
3848 size_t unknown_size;
Paul Yang60327462017-10-09 12:39:13 -07003849
3850 for (i = m->field_count - 1; i >= 0; i--) {
Paul Yang9bda1f12018-09-22 18:57:43 -07003851 const upb_msglayout_field *f = &m->fields[i];
Paul Yang60327462017-10-09 12:39:13 -07003852
3853 if (f->label == UPB_LABEL_REPEATED) {
3854 CHK(upb_encode_array(e, msg + f->offset, m, f));
3855 } else {
Paul Yang9bda1f12018-09-22 18:57:43 -07003856 bool skip_empty = false;
3857 if (f->presence == 0) {
3858 /* Proto3 presence. */
3859 skip_empty = true;
3860 } else if (f->presence > 0) {
3861 /* Proto2 presence: hasbit. */
3862 if (!upb_readhasbit(msg, f)) {
3863 continue;
3864 }
3865 } else {
3866 /* Field is in a oneof. */
3867 if (upb_readcase(msg, f) != f->number) {
3868 continue;
Paul Yang6dd563a2018-03-08 17:35:22 -08003869 }
Paul Yang60327462017-10-09 12:39:13 -07003870 }
Paul Yang9bda1f12018-09-22 18:57:43 -07003871 CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
Paul Yang60327462017-10-09 12:39:13 -07003872 }
3873 }
3874
Paul Yang9bda1f12018-09-22 18:57:43 -07003875 unknown = upb_msg_getunknown(msg, &unknown_size);
3876
3877 if (unknown) {
3878 upb_put_bytes(e, unknown, unknown_size);
3879 }
3880
Paul Yang6dd563a2018-03-08 17:35:22 -08003881 *size = (e->limit - e->ptr) - pre_len;
Paul Yang60327462017-10-09 12:39:13 -07003882 return true;
3883}
3884
Paul Yang9bda1f12018-09-22 18:57:43 -07003885char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
3886 size_t *size) {
Paul Yang60327462017-10-09 12:39:13 -07003887 upb_encstate e;
Paul Yang9bda1f12018-09-22 18:57:43 -07003888 e.alloc = upb_arena_alloc(arena);
Paul Yang60327462017-10-09 12:39:13 -07003889 e.buf = NULL;
3890 e.limit = NULL;
3891 e.ptr = NULL;
3892
3893 if (!upb_encode_message(&e, msg, m, size)) {
3894 *size = 0;
3895 return NULL;
3896 }
3897
3898 *size = e.limit - e.ptr;
3899
3900 if (*size == 0) {
3901 static char ch;
3902 return &ch;
3903 } else {
3904 UPB_ASSERT(e.ptr);
3905 return e.ptr;
3906 }
3907}
3908
3909#undef CHK
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003910/*
3911** TODO(haberman): it's unclear whether a lot of the consistency checks should
Paul Yange0e54662016-09-15 11:09:01 -07003912** UPB_ASSERT() or return false.
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003913*/
3914
3915
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003916#include <string.h>
3917
3918
Paul Yange0e54662016-09-15 11:09:01 -07003919static void *upb_calloc(size_t size) {
3920 void *mem = upb_gmalloc(size);
3921 if (mem) {
3922 memset(mem, 0, size);
3923 }
3924 return mem;
3925}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003926
3927/* Defined for the sole purpose of having a unique pointer value for
3928 * UPB_NO_CLOSURE. */
3929char _upb_noclosure;
3930
3931static void freehandlers(upb_refcounted *r) {
3932 upb_handlers *h = (upb_handlers*)r;
3933
3934 upb_inttable_iter i;
3935 upb_inttable_begin(&i, &h->cleanup_);
3936 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
3937 void *val = (void*)upb_inttable_iter_key(&i);
3938 upb_value func_val = upb_inttable_iter_value(&i);
3939 upb_handlerfree *func = upb_value_getfptr(func_val);
3940 func(val);
3941 }
3942
3943 upb_inttable_uninit(&h->cleanup_);
3944 upb_msgdef_unref(h->msg, h);
Paul Yange0e54662016-09-15 11:09:01 -07003945 upb_gfree(h->sub);
3946 upb_gfree(h);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07003947}
3948
3949static void visithandlers(const upb_refcounted *r, upb_refcounted_visit *visit,
3950 void *closure) {
3951 const upb_handlers *h = (const upb_handlers*)r;
3952 upb_msg_field_iter i;
3953 for(upb_msg_field_begin(&i, h->msg);
3954 !upb_msg_field_done(&i);
3955 upb_msg_field_next(&i)) {
3956 upb_fielddef *f = upb_msg_iter_field(&i);
3957 const upb_handlers *sub;
3958 if (!upb_fielddef_issubmsg(f)) continue;
3959 sub = upb_handlers_getsubhandlers(h, f);
3960 if (sub) visit(r, upb_handlers_upcast(sub), closure);
3961 }
3962}
3963
3964static const struct upb_refcounted_vtbl vtbl = {visithandlers, freehandlers};
3965
3966typedef struct {
3967 upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */
3968 upb_handlers_callback *callback;
3969 const void *closure;
3970} dfs_state;
3971
3972/* TODO(haberman): discard upb_handlers* objects that do not actually have any
3973 * handlers set and cannot reach any upb_handlers* object that does. This is
3974 * slightly tricky to do correctly. */
3975static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
3976 dfs_state *s) {
3977 upb_msg_field_iter i;
3978 upb_handlers *h = upb_handlers_new(m, owner);
3979 if (!h) return NULL;
3980 if (!upb_inttable_insertptr(&s->tab, m, upb_value_ptr(h))) goto oom;
3981
3982 s->callback(s->closure, h);
3983
3984 /* For each submessage field, get or create a handlers object and set it as
3985 * the subhandlers. */
3986 for(upb_msg_field_begin(&i, m);
3987 !upb_msg_field_done(&i);
3988 upb_msg_field_next(&i)) {
3989 upb_fielddef *f = upb_msg_iter_field(&i);
3990 const upb_msgdef *subdef;
3991 upb_value subm_ent;
3992
3993 if (!upb_fielddef_issubmsg(f)) continue;
3994
3995 subdef = upb_downcast_msgdef(upb_fielddef_subdef(f));
3996 if (upb_inttable_lookupptr(&s->tab, subdef, &subm_ent)) {
3997 upb_handlers_setsubhandlers(h, f, upb_value_getptr(subm_ent));
3998 } else {
3999 upb_handlers *sub_mh = newformsg(subdef, &sub_mh, s);
4000 if (!sub_mh) goto oom;
4001 upb_handlers_setsubhandlers(h, f, sub_mh);
4002 upb_handlers_unref(sub_mh, &sub_mh);
4003 }
4004 }
4005 return h;
4006
4007oom:
4008 upb_handlers_unref(h, owner);
4009 return NULL;
4010}
4011
4012/* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
4013 * subhandlers for this submessage field. */
4014#define SUBH(h, selector) (h->sub[selector])
4015
4016/* The selector for a submessage field is the field index. */
4017#define SUBH_F(h, f) SUBH(h, f->index_)
4018
4019static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
4020 upb_handlertype_t type) {
4021 upb_selector_t sel;
Paul Yange0e54662016-09-15 11:09:01 -07004022 UPB_ASSERT(!upb_handlers_isfrozen(h));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004023 if (upb_handlers_msgdef(h) != upb_fielddef_containingtype(f)) {
4024 upb_status_seterrf(
4025 &h->status_, "type mismatch: field %s does not belong to message %s",
4026 upb_fielddef_name(f), upb_msgdef_fullname(upb_handlers_msgdef(h)));
4027 return -1;
4028 }
4029 if (!upb_handlers_getselector(f, type, &sel)) {
4030 upb_status_seterrf(
4031 &h->status_,
4032 "type mismatch: cannot register handler type %d for field %s",
4033 type, upb_fielddef_name(f));
4034 return -1;
4035 }
4036 return sel;
4037}
4038
4039static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f,
4040 upb_handlertype_t type) {
4041 int32_t sel = trygetsel(h, f, type);
Paul Yange0e54662016-09-15 11:09:01 -07004042 UPB_ASSERT(sel >= 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004043 return sel;
4044}
4045
4046static const void **returntype(upb_handlers *h, const upb_fielddef *f,
4047 upb_handlertype_t type) {
4048 return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type_;
4049}
4050
4051static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
4052 upb_handlertype_t type, upb_func *func,
4053 upb_handlerattr *attr) {
4054 upb_handlerattr set_attr = UPB_HANDLERATTR_INITIALIZER;
4055 const void *closure_type;
4056 const void **context_closure_type;
4057
Paul Yange0e54662016-09-15 11:09:01 -07004058 UPB_ASSERT(!upb_handlers_isfrozen(h));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004059
4060 if (sel < 0) {
4061 upb_status_seterrmsg(&h->status_,
4062 "incorrect handler type for this field.");
4063 return false;
4064 }
4065
4066 if (h->table[sel].func) {
4067 upb_status_seterrmsg(&h->status_,
4068 "cannot change handler once it has been set.");
4069 return false;
4070 }
4071
4072 if (attr) {
4073 set_attr = *attr;
4074 }
4075
4076 /* Check that the given closure type matches the closure type that has been
4077 * established for this context (if any). */
4078 closure_type = upb_handlerattr_closuretype(&set_attr);
4079
4080 if (type == UPB_HANDLER_STRING) {
4081 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
4082 } else if (f && upb_fielddef_isseq(f) &&
4083 type != UPB_HANDLER_STARTSEQ &&
4084 type != UPB_HANDLER_ENDSEQ) {
4085 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
4086 } else {
4087 context_closure_type = &h->top_closure_type;
4088 }
4089
4090 if (closure_type && *context_closure_type &&
4091 closure_type != *context_closure_type) {
4092 /* TODO(haberman): better message for debugging. */
4093 if (f) {
4094 upb_status_seterrf(&h->status_,
4095 "closure type does not match for field %s",
4096 upb_fielddef_name(f));
4097 } else {
4098 upb_status_seterrmsg(
4099 &h->status_, "closure type does not match for message-level handler");
4100 }
4101 return false;
4102 }
4103
4104 if (closure_type)
4105 *context_closure_type = closure_type;
4106
4107 /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
4108 * matches any pre-existing expectations about what type is expected. */
4109 if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) {
4110 const void *return_type = upb_handlerattr_returnclosuretype(&set_attr);
4111 const void *table_return_type =
4112 upb_handlerattr_returnclosuretype(&h->table[sel].attr);
4113 if (return_type && table_return_type && return_type != table_return_type) {
4114 upb_status_seterrmsg(&h->status_, "closure return type does not match");
4115 return false;
4116 }
4117
4118 if (table_return_type && !return_type)
4119 upb_handlerattr_setreturnclosuretype(&set_attr, table_return_type);
4120 }
4121
4122 h->table[sel].func = (upb_func*)func;
4123 h->table[sel].attr = set_attr;
4124 return true;
4125}
4126
4127/* Returns the effective closure type for this handler (which will propagate
4128 * from outer frames if this frame has no START* handler). Not implemented for
4129 * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is
4130 * the effective closure type is unspecified (either no handler was registered
4131 * to specify it or the handler that was registered did not specify the closure
4132 * type). */
4133const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f,
4134 upb_handlertype_t type) {
4135 const void *ret;
4136 upb_selector_t sel;
4137
Paul Yange0e54662016-09-15 11:09:01 -07004138 UPB_ASSERT(type != UPB_HANDLER_STRING);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004139 ret = h->top_closure_type;
4140
4141 if (upb_fielddef_isseq(f) &&
4142 type != UPB_HANDLER_STARTSEQ &&
4143 type != UPB_HANDLER_ENDSEQ &&
4144 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
4145 ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
4146 }
4147
4148 if (type == UPB_HANDLER_STRING &&
4149 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
4150 ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
4151 }
4152
4153 /* The effective type of the submessage; not used yet.
4154 * if (type == SUBMESSAGE &&
4155 * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
4156 * ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
4157 * } */
4158
4159 return ret;
4160}
4161
4162/* Checks whether the START* handler specified by f & type is missing even
4163 * though it is required to convert the established type of an outer frame
4164 * ("closure_type") into the established type of an inner frame (represented in
4165 * the return closure type of this handler's attr. */
4166bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type,
4167 upb_status *status) {
4168 const void *closure_type;
4169 const upb_handlerattr *attr;
4170 const void *return_closure_type;
4171
4172 upb_selector_t sel = handlers_getsel(h, f, type);
4173 if (h->table[sel].func) return true;
4174 closure_type = effective_closure_type(h, f, type);
4175 attr = &h->table[sel].attr;
4176 return_closure_type = upb_handlerattr_returnclosuretype(attr);
4177 if (closure_type && return_closure_type &&
4178 closure_type != return_closure_type) {
4179 upb_status_seterrf(status,
4180 "expected start handler to return sub type for field %f",
4181 upb_fielddef_name(f));
4182 return false;
4183 }
4184 return true;
4185}
4186
4187/* Public interface ***********************************************************/
4188
4189upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
4190 int extra;
4191 upb_handlers *h;
4192
Paul Yange0e54662016-09-15 11:09:01 -07004193 UPB_ASSERT(upb_msgdef_isfrozen(md));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004194
4195 extra = sizeof(upb_handlers_tabent) * (md->selector_count - 1);
Paul Yange0e54662016-09-15 11:09:01 -07004196 h = upb_calloc(sizeof(*h) + extra);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004197 if (!h) return NULL;
4198
4199 h->msg = md;
4200 upb_msgdef_ref(h->msg, h);
4201 upb_status_clear(&h->status_);
Paul Yange0e54662016-09-15 11:09:01 -07004202
4203 if (md->submsg_field_count > 0) {
4204 h->sub = upb_calloc(md->submsg_field_count * sizeof(*h->sub));
4205 if (!h->sub) goto oom;
4206 } else {
4207 h->sub = 0;
4208 }
4209
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004210 if (!upb_refcounted_init(upb_handlers_upcast_mutable(h), &vtbl, owner))
4211 goto oom;
4212 if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
4213
4214 /* calloc() above initialized all handlers to NULL. */
4215 return h;
4216
4217oom:
4218 freehandlers(upb_handlers_upcast_mutable(h));
4219 return NULL;
4220}
4221
4222const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
4223 const void *owner,
4224 upb_handlers_callback *callback,
4225 const void *closure) {
4226 dfs_state state;
4227 upb_handlers *ret;
4228 bool ok;
4229 upb_refcounted *r;
4230
4231 state.callback = callback;
4232 state.closure = closure;
4233 if (!upb_inttable_init(&state.tab, UPB_CTYPE_PTR)) return NULL;
4234
4235 ret = newformsg(m, owner, &state);
4236
4237 upb_inttable_uninit(&state.tab);
4238 if (!ret) return NULL;
4239
4240 r = upb_handlers_upcast_mutable(ret);
4241 ok = upb_refcounted_freeze(&r, 1, NULL, UPB_MAX_HANDLER_DEPTH);
Paul Yange0e54662016-09-15 11:09:01 -07004242 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004243
4244 return ret;
4245}
4246
4247const upb_status *upb_handlers_status(upb_handlers *h) {
Paul Yange0e54662016-09-15 11:09:01 -07004248 UPB_ASSERT(!upb_handlers_isfrozen(h));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004249 return &h->status_;
4250}
4251
4252void upb_handlers_clearerr(upb_handlers *h) {
Paul Yange0e54662016-09-15 11:09:01 -07004253 UPB_ASSERT(!upb_handlers_isfrozen(h));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004254 upb_status_clear(&h->status_);
4255}
4256
4257#define SETTER(name, handlerctype, handlertype) \
4258 bool upb_handlers_set ## name(upb_handlers *h, const upb_fielddef *f, \
4259 handlerctype func, upb_handlerattr *attr) { \
4260 int32_t sel = trygetsel(h, f, handlertype); \
4261 return doset(h, sel, f, handlertype, (upb_func*)func, attr); \
4262 }
4263
4264SETTER(int32, upb_int32_handlerfunc*, UPB_HANDLER_INT32)
4265SETTER(int64, upb_int64_handlerfunc*, UPB_HANDLER_INT64)
4266SETTER(uint32, upb_uint32_handlerfunc*, UPB_HANDLER_UINT32)
4267SETTER(uint64, upb_uint64_handlerfunc*, UPB_HANDLER_UINT64)
4268SETTER(float, upb_float_handlerfunc*, UPB_HANDLER_FLOAT)
4269SETTER(double, upb_double_handlerfunc*, UPB_HANDLER_DOUBLE)
4270SETTER(bool, upb_bool_handlerfunc*, UPB_HANDLER_BOOL)
4271SETTER(startstr, upb_startstr_handlerfunc*, UPB_HANDLER_STARTSTR)
4272SETTER(string, upb_string_handlerfunc*, UPB_HANDLER_STRING)
4273SETTER(endstr, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSTR)
4274SETTER(startseq, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSEQ)
4275SETTER(startsubmsg, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSUBMSG)
4276SETTER(endsubmsg, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSUBMSG)
4277SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
4278
4279#undef SETTER
4280
Paul Yang60327462017-10-09 12:39:13 -07004281bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
4282 upb_handlerattr *attr) {
4283 return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
4284 (upb_func *)func, attr);
4285}
4286
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004287bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
4288 upb_handlerattr *attr) {
4289 return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
4290 (upb_func *)func, attr);
4291}
4292
4293bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
4294 upb_handlerattr *attr) {
Paul Yange0e54662016-09-15 11:09:01 -07004295 UPB_ASSERT(!upb_handlers_isfrozen(h));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004296 return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
4297 (upb_func *)func, attr);
4298}
4299
4300bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
4301 const upb_handlers *sub) {
Paul Yange0e54662016-09-15 11:09:01 -07004302 UPB_ASSERT(sub);
4303 UPB_ASSERT(!upb_handlers_isfrozen(h));
4304 UPB_ASSERT(upb_fielddef_issubmsg(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004305 if (SUBH_F(h, f)) return false; /* Can't reset. */
4306 if (upb_msgdef_upcast(upb_handlers_msgdef(sub)) != upb_fielddef_subdef(f)) {
4307 return false;
4308 }
4309 SUBH_F(h, f) = sub;
4310 upb_ref2(sub, h);
4311 return true;
4312}
4313
4314const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
4315 const upb_fielddef *f) {
Paul Yange0e54662016-09-15 11:09:01 -07004316 UPB_ASSERT(upb_fielddef_issubmsg(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004317 return SUBH_F(h, f);
4318}
4319
4320bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
4321 upb_handlerattr *attr) {
4322 if (!upb_handlers_gethandler(h, sel))
4323 return false;
4324 *attr = h->table[sel].attr;
4325 return true;
4326}
4327
4328const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
4329 upb_selector_t sel) {
4330 /* STARTSUBMSG selector in sel is the field's selector base. */
4331 return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
4332}
4333
4334const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
4335
4336bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
4337 bool ok;
4338 if (upb_inttable_lookupptr(&h->cleanup_, p, NULL)) {
4339 return false;
4340 }
4341 ok = upb_inttable_insertptr(&h->cleanup_, p, upb_value_fptr(func));
Paul Yange0e54662016-09-15 11:09:01 -07004342 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004343 return true;
4344}
4345
4346
4347/* "Static" methods ***********************************************************/
4348
4349bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s) {
4350 /* TODO: verify we have a transitive closure. */
4351 int i;
4352 for (i = 0; i < n; i++) {
4353 upb_msg_field_iter j;
4354 upb_handlers *h = handlers[i];
4355
4356 if (!upb_ok(&h->status_)) {
4357 upb_status_seterrf(s, "handlers for message %s had error status: %s",
4358 upb_msgdef_fullname(upb_handlers_msgdef(h)),
4359 upb_status_errmsg(&h->status_));
4360 return false;
4361 }
4362
4363 /* Check that there are no closure mismatches due to missing Start* handlers
4364 * or subhandlers with different type-level types. */
4365 for(upb_msg_field_begin(&j, h->msg);
4366 !upb_msg_field_done(&j);
4367 upb_msg_field_next(&j)) {
4368
4369 const upb_fielddef *f = upb_msg_iter_field(&j);
4370 if (upb_fielddef_isseq(f)) {
4371 if (!checkstart(h, f, UPB_HANDLER_STARTSEQ, s))
4372 return false;
4373 }
4374
4375 if (upb_fielddef_isstring(f)) {
4376 if (!checkstart(h, f, UPB_HANDLER_STARTSTR, s))
4377 return false;
4378 }
4379
4380 if (upb_fielddef_issubmsg(f)) {
4381 bool hashandler = false;
4382 if (upb_handlers_gethandler(
4383 h, handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)) ||
4384 upb_handlers_gethandler(
4385 h, handlers_getsel(h, f, UPB_HANDLER_ENDSUBMSG))) {
4386 hashandler = true;
4387 }
4388
4389 if (upb_fielddef_isseq(f) &&
4390 (upb_handlers_gethandler(
4391 h, handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)) ||
4392 upb_handlers_gethandler(
4393 h, handlers_getsel(h, f, UPB_HANDLER_ENDSEQ)))) {
4394 hashandler = true;
4395 }
4396
4397 if (hashandler && !upb_handlers_getsubhandlers(h, f)) {
4398 /* For now we add an empty subhandlers in this case. It makes the
4399 * decoder code generator simpler, because it only has to handle two
4400 * cases (submessage has handlers or not) as opposed to three
4401 * (submessage has handlers in enclosing message but no subhandlers).
4402 *
4403 * This makes parsing less efficient in the case that we want to
4404 * notice a submessage but skip its contents (like if we're testing
4405 * for submessage presence or counting the number of repeated
4406 * submessages). In this case we will end up parsing the submessage
4407 * field by field and throwing away the results for each, instead of
4408 * skipping the whole delimited thing at once. If this is an issue we
4409 * can revisit it, but do remember that this only arises when you have
4410 * handlers (startseq/startsubmsg/endsubmsg/endseq) set for the
4411 * submessage but no subhandlers. The uses cases for this are
4412 * limited. */
4413 upb_handlers *sub = upb_handlers_new(upb_fielddef_msgsubdef(f), &sub);
4414 upb_handlers_setsubhandlers(h, f, sub);
4415 upb_handlers_unref(sub, &sub);
4416 }
4417
4418 /* TODO(haberman): check type of submessage.
4419 * This is slightly tricky; also consider whether we should check that
4420 * they match at setsubhandlers time. */
4421 }
4422 }
4423 }
4424
4425 if (!upb_refcounted_freeze((upb_refcounted*const*)handlers, n, s,
4426 UPB_MAX_HANDLER_DEPTH)) {
4427 return false;
4428 }
4429
4430 return true;
4431}
4432
4433upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) {
4434 switch (upb_fielddef_type(f)) {
4435 case UPB_TYPE_INT32:
4436 case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
4437 case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
4438 case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
4439 case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
4440 case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
4441 case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
4442 case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
Paul Yange0e54662016-09-15 11:09:01 -07004443 default: UPB_ASSERT(false); return -1; /* Invalid input. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004444 }
4445}
4446
4447bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
4448 upb_selector_t *s) {
4449 switch (type) {
4450 case UPB_HANDLER_INT32:
4451 case UPB_HANDLER_INT64:
4452 case UPB_HANDLER_UINT32:
4453 case UPB_HANDLER_UINT64:
4454 case UPB_HANDLER_FLOAT:
4455 case UPB_HANDLER_DOUBLE:
4456 case UPB_HANDLER_BOOL:
4457 if (!upb_fielddef_isprimitive(f) ||
4458 upb_handlers_getprimitivehandlertype(f) != type)
4459 return false;
4460 *s = f->selector_base;
4461 break;
4462 case UPB_HANDLER_STRING:
4463 if (upb_fielddef_isstring(f)) {
4464 *s = f->selector_base;
4465 } else if (upb_fielddef_lazy(f)) {
4466 *s = f->selector_base + 3;
4467 } else {
4468 return false;
4469 }
4470 break;
4471 case UPB_HANDLER_STARTSTR:
4472 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
4473 *s = f->selector_base + 1;
4474 } else {
4475 return false;
4476 }
4477 break;
4478 case UPB_HANDLER_ENDSTR:
4479 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
4480 *s = f->selector_base + 2;
4481 } else {
4482 return false;
4483 }
4484 break;
4485 case UPB_HANDLER_STARTSEQ:
4486 if (!upb_fielddef_isseq(f)) return false;
4487 *s = f->selector_base - 2;
4488 break;
4489 case UPB_HANDLER_ENDSEQ:
4490 if (!upb_fielddef_isseq(f)) return false;
4491 *s = f->selector_base - 1;
4492 break;
4493 case UPB_HANDLER_STARTSUBMSG:
4494 if (!upb_fielddef_issubmsg(f)) return false;
4495 /* Selectors for STARTSUBMSG are at the beginning of the table so that the
4496 * selector can also be used as an index into the "sub" array of
4497 * subhandlers. The indexes for the two into these two tables are the
4498 * same, except that in the handler table the static selectors come first. */
4499 *s = f->index_ + UPB_STATIC_SELECTOR_COUNT;
4500 break;
4501 case UPB_HANDLER_ENDSUBMSG:
4502 if (!upb_fielddef_issubmsg(f)) return false;
4503 *s = f->selector_base;
4504 break;
4505 }
Paul Yange0e54662016-09-15 11:09:01 -07004506 UPB_ASSERT((size_t)*s < upb_fielddef_containingtype(f)->selector_count);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07004507 return true;
4508}
4509
4510uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
4511 return upb_fielddef_isseq(f) ? 2 : 0;
4512}
4513
4514uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
4515 uint32_t ret = 1;
4516 if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
4517 if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
4518 if (upb_fielddef_issubmsg(f)) {
4519 /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
4520 ret += 0;
4521 if (upb_fielddef_lazy(f)) {
4522 /* STARTSTR/ENDSTR/STRING (for lazy) */
4523 ret += 3;
4524 }
4525 }
4526 return ret;
4527}
4528
4529
4530/* upb_handlerattr ************************************************************/
4531
4532void upb_handlerattr_init(upb_handlerattr *attr) {
4533 upb_handlerattr from = UPB_HANDLERATTR_INITIALIZER;
4534 memcpy(attr, &from, sizeof(*attr));
4535}
4536
4537void upb_handlerattr_uninit(upb_handlerattr *attr) {
4538 UPB_UNUSED(attr);
4539}
4540
4541bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd) {
4542 attr->handler_data_ = hd;
4543 return true;
4544}
4545
4546bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type) {
4547 attr->closure_type_ = type;
4548 return true;
4549}
4550
4551const void *upb_handlerattr_closuretype(const upb_handlerattr *attr) {
4552 return attr->closure_type_;
4553}
4554
4555bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
4556 const void *type) {
4557 attr->return_closure_type_ = type;
4558 return true;
4559}
4560
4561const void *upb_handlerattr_returnclosuretype(const upb_handlerattr *attr) {
4562 return attr->return_closure_type_;
4563}
4564
4565bool upb_handlerattr_setalwaysok(upb_handlerattr *attr, bool alwaysok) {
4566 attr->alwaysok_ = alwaysok;
4567 return true;
4568}
4569
4570bool upb_handlerattr_alwaysok(const upb_handlerattr *attr) {
4571 return attr->alwaysok_;
4572}
4573
4574/* upb_bufhandle **************************************************************/
4575
4576size_t upb_bufhandle_objofs(const upb_bufhandle *h) {
4577 return h->objofs_;
4578}
4579
4580/* upb_byteshandler ***********************************************************/
4581
4582void upb_byteshandler_init(upb_byteshandler* h) {
4583 memset(h, 0, sizeof(*h));
4584}
4585
4586/* For when we support handlerfree callbacks. */
4587void upb_byteshandler_uninit(upb_byteshandler* h) {
4588 UPB_UNUSED(h);
4589}
4590
4591bool upb_byteshandler_setstartstr(upb_byteshandler *h,
4592 upb_startstr_handlerfunc *func, void *d) {
4593 h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
4594 h->table[UPB_STARTSTR_SELECTOR].attr.handler_data_ = d;
4595 return true;
4596}
4597
4598bool upb_byteshandler_setstring(upb_byteshandler *h,
4599 upb_string_handlerfunc *func, void *d) {
4600 h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
4601 h->table[UPB_STRING_SELECTOR].attr.handler_data_ = d;
4602 return true;
4603}
4604
4605bool upb_byteshandler_setendstr(upb_byteshandler *h,
4606 upb_endfield_handlerfunc *func, void *d) {
4607 h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
4608 h->table[UPB_ENDSTR_SELECTOR].attr.handler_data_ = d;
4609 return true;
4610}
Paul Yang5a3405c2017-02-06 12:40:51 -08004611
4612
Paul Yang5a3405c2017-02-06 12:40:51 -08004613/** Handlers for upb_msg ******************************************************/
4614
4615typedef struct {
4616 size_t offset;
4617 int32_t hasbit;
4618} upb_msg_handlerdata;
4619
4620/* Fallback implementation if the handler is not specialized by the producer. */
4621#define MSG_WRITER(type, ctype) \
4622 bool upb_msg_set ## type (void *c, const void *hd, ctype val) { \
4623 uint8_t *m = c; \
4624 const upb_msg_handlerdata *d = hd; \
4625 if (d->hasbit > 0) \
4626 *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
4627 *(ctype*)&m[d->offset] = val; \
4628 return true; \
4629 } \
4630
4631MSG_WRITER(double, double)
4632MSG_WRITER(float, float)
4633MSG_WRITER(int32, int32_t)
4634MSG_WRITER(int64, int64_t)
4635MSG_WRITER(uint32, uint32_t)
4636MSG_WRITER(uint64, uint64_t)
4637MSG_WRITER(bool, bool)
4638
4639bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f,
4640 size_t offset, int32_t hasbit) {
4641 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
4642 bool ok;
4643
4644 upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d));
4645 if (!d) return false;
4646 d->offset = offset;
4647 d->hasbit = hasbit;
4648
4649 upb_handlerattr_sethandlerdata(&attr, d);
4650 upb_handlerattr_setalwaysok(&attr, true);
4651 upb_handlers_addcleanup(h, d, upb_gfree);
4652
4653#define TYPE(u, l) \
4654 case UPB_TYPE_##u: \
4655 ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break;
4656
4657 ok = false;
4658
4659 switch (upb_fielddef_type(f)) {
4660 TYPE(INT64, int64);
4661 TYPE(INT32, int32);
4662 TYPE(ENUM, int32);
4663 TYPE(UINT64, uint64);
4664 TYPE(UINT32, uint32);
4665 TYPE(DOUBLE, double);
4666 TYPE(FLOAT, float);
4667 TYPE(BOOL, bool);
4668 default: UPB_ASSERT(false); break;
4669 }
4670#undef TYPE
4671
4672 upb_handlerattr_uninit(&attr);
4673 return ok;
4674}
4675
4676bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
4677 upb_selector_t s,
4678 upb_fieldtype_t *type,
4679 size_t *offset,
4680 int32_t *hasbit) {
4681 const upb_msg_handlerdata *d;
4682 upb_func *f = upb_handlers_gethandler(h, s);
4683
4684 if ((upb_int64_handlerfunc*)f == upb_msg_setint64) {
4685 *type = UPB_TYPE_INT64;
4686 } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) {
4687 *type = UPB_TYPE_INT32;
4688 } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) {
4689 *type = UPB_TYPE_UINT64;
4690 } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) {
4691 *type = UPB_TYPE_UINT32;
4692 } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) {
4693 *type = UPB_TYPE_DOUBLE;
4694 } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) {
4695 *type = UPB_TYPE_FLOAT;
4696 } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) {
4697 *type = UPB_TYPE_BOOL;
4698 } else {
4699 return false;
4700 }
4701
4702 d = upb_handlers_gethandlerdata(h, s);
4703 *offset = d->offset;
4704 *hasbit = d->hasbit;
4705 return true;
4706}
Paul Yang9bda1f12018-09-22 18:57:43 -07004707
4708
4709bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
4710 return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
4711 type == UPB_TYPE_UINT32 || type == UPB_TYPE_INT64 ||
4712 type == UPB_TYPE_UINT64 || type == UPB_TYPE_STRING;
4713}
4714
4715#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
4716#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
4717#define ENCODE_MAX_NESTING 64
4718#define CHECK_TRUE(x) if (!(x)) { return false; }
4719
4720/** upb_msgval ****************************************************************/
4721
4722#define upb_alignof(t) offsetof(struct { char c; t x; }, x)
4723
4724/* These functions will generate real memcpy() calls on ARM sadly, because
4725 * the compiler assumes they might not be aligned. */
4726
4727static upb_msgval upb_msgval_read(const void *p, size_t ofs,
4728 uint8_t size) {
4729 upb_msgval val;
4730 p = (char*)p + ofs;
4731 memcpy(&val, p, size);
4732 return val;
4733}
4734
4735static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
4736 uint8_t size) {
4737 p = (char*)p + ofs;
4738 memcpy(p, &val, size);
4739}
4740
4741static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
4742 switch (type) {
4743 case UPB_TYPE_DOUBLE:
4744 case UPB_TYPE_INT64:
4745 case UPB_TYPE_UINT64:
4746 return 8;
4747 case UPB_TYPE_ENUM:
4748 case UPB_TYPE_INT32:
4749 case UPB_TYPE_UINT32:
4750 case UPB_TYPE_FLOAT:
4751 return 4;
4752 case UPB_TYPE_BOOL:
4753 return 1;
4754 case UPB_TYPE_MESSAGE:
4755 return sizeof(void*);
4756 case UPB_TYPE_BYTES:
4757 case UPB_TYPE_STRING:
Paul Yang57b65972019-03-19 22:27:13 -07004758 return sizeof(upb_strview);
Paul Yang9bda1f12018-09-22 18:57:43 -07004759 }
4760 UPB_UNREACHABLE();
4761}
4762
4763static uint8_t upb_msg_fieldsize(const upb_msglayout_field *field) {
4764 if (field->label == UPB_LABEL_REPEATED) {
4765 return sizeof(void*);
4766 } else {
4767 return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
4768 }
4769}
4770
4771/* TODO(haberman): this is broken right now because upb_msgval can contain
4772 * a char* / size_t pair, which is too big for a upb_value. To fix this
4773 * we'll probably need to dynamically allocate a upb_msgval and store a
4774 * pointer to that in the tables for extensions/maps. */
4775static upb_value upb_toval(upb_msgval val) {
4776 upb_value ret;
4777 UPB_UNUSED(val);
4778 memset(&ret, 0, sizeof(upb_value)); /* XXX */
4779 return ret;
4780}
4781
4782static upb_msgval upb_msgval_fromval(upb_value val) {
4783 upb_msgval ret;
4784 UPB_UNUSED(val);
4785 memset(&ret, 0, sizeof(upb_msgval)); /* XXX */
4786 return ret;
4787}
4788
4789static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
4790 switch (type) {
4791 case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
4792 case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
4793 case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
4794 case UPB_TYPE_BYTES:
4795 case UPB_TYPE_MESSAGE:
4796 case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
4797 case UPB_TYPE_ENUM:
4798 case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
4799 case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
4800 case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
4801 case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
4802 default: UPB_ASSERT(false); return 0;
4803 }
4804}
4805
4806
4807/** upb_msg *******************************************************************/
4808
4809/* If we always read/write as a consistent type to each address, this shouldn't
4810 * violate aliasing.
4811 */
4812#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
4813
4814/* Internal members of a upb_msg. We can change this without breaking binary
4815 * compatibility. We put these before the user's data. The user's upb_msg*
4816 * points after the upb_msg_internal. */
4817
4818/* Used when a message is not extendable. */
4819typedef struct {
4820 /* TODO(haberman): use pointer tagging so we we are slim when known unknown
4821 * fields are not present. */
4822 upb_arena *arena;
4823 char *unknown;
4824 size_t unknown_len;
4825 size_t unknown_size;
4826} upb_msg_internal;
4827
4828/* Used when a message is extendable. */
4829typedef struct {
4830 upb_inttable *extdict;
4831 upb_msg_internal base;
4832} upb_msg_internal_withext;
4833
4834static int upb_msg_internalsize(const upb_msglayout *l) {
4835 return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
4836}
4837
4838static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
4839 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
4840}
4841
4842static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
4843 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
4844}
4845
4846static upb_msg_internal_withext *upb_msg_getinternalwithext(
4847 upb_msg *msg, const upb_msglayout *l) {
4848 UPB_ASSERT(l->extendable);
4849 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
4850}
4851
4852void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len) {
4853 upb_msg_internal* in = upb_msg_getinternal(msg);
4854 if (len > in->unknown_size - in->unknown_len) {
4855 upb_alloc *alloc = upb_arena_alloc(in->arena);
4856 size_t need = in->unknown_size + len;
4857 size_t newsize = UPB_MAX(in->unknown_size * 2, need);
4858 in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
4859 in->unknown_size = newsize;
4860 }
4861 memcpy(in->unknown + in->unknown_len, data, len);
4862 in->unknown_len += len;
4863}
4864
4865const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
4866 const upb_msg_internal* in = upb_msg_getinternal_const(msg);
4867 *len = in->unknown_len;
4868 return in->unknown;
4869}
4870
4871static const upb_msglayout_field *upb_msg_checkfield(int field_index,
4872 const upb_msglayout *l) {
4873 UPB_ASSERT(field_index >= 0 && field_index < l->field_count);
4874 return &l->fields[field_index];
4875}
4876
4877static bool upb_msg_inoneof(const upb_msglayout_field *field) {
4878 return field->presence < 0;
4879}
4880
4881static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
4882 const upb_msglayout *l) {
4883 const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4884 UPB_ASSERT(upb_msg_inoneof(field));
4885 return PTR_AT(msg, ~field->presence, uint32_t);
4886}
4887
4888static size_t upb_msg_sizeof(const upb_msglayout *l) {
4889 return l->size + upb_msg_internalsize(l);
4890}
4891
4892upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) {
4893 upb_alloc *alloc = upb_arena_alloc(a);
4894 void *mem = upb_malloc(alloc, upb_msg_sizeof(l));
4895 upb_msg_internal *in;
4896 upb_msg *msg;
4897
4898 if (!mem) {
4899 return NULL;
4900 }
4901
4902 msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
4903
4904 /* Initialize normal members. */
4905 memset(msg, 0, l->size);
4906
4907 /* Initialize internal members. */
4908 in = upb_msg_getinternal(msg);
4909 in->arena = a;
4910 in->unknown = NULL;
4911 in->unknown_len = 0;
4912 in->unknown_size = 0;
4913
4914 if (l->extendable) {
4915 upb_msg_getinternalwithext(msg, l)->extdict = NULL;
4916 }
4917
4918 return msg;
4919}
4920
4921upb_arena *upb_msg_arena(const upb_msg *msg) {
4922 return upb_msg_getinternal_const(msg)->arena;
4923}
4924
4925bool upb_msg_has(const upb_msg *msg,
4926 int field_index,
4927 const upb_msglayout *l) {
4928 const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4929
4930 UPB_ASSERT(field->presence);
4931
4932 if (upb_msg_inoneof(field)) {
4933 /* Oneofs are set when the oneof number is set to this field. */
4934 return *upb_msg_oneofcase(msg, field_index, l) == field->number;
4935 } else {
4936 /* Other fields are set when their hasbit is set. */
4937 uint32_t hasbit = field->presence;
4938 return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
4939 }
4940}
4941
4942upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
4943 const upb_msglayout *l) {
4944 const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4945 int size = upb_msg_fieldsize(field);
4946 return upb_msgval_read(msg, field->offset, size);
4947}
4948
4949void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
4950 const upb_msglayout *l) {
4951 const upb_msglayout_field *field = upb_msg_checkfield(field_index, l);
4952 int size = upb_msg_fieldsize(field);
4953 upb_msgval_write(msg, field->offset, val, size);
4954}
4955
4956
4957/** upb_array *****************************************************************/
4958
4959#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
4960
4961upb_array *upb_array_new(upb_fieldtype_t type, upb_arena *a) {
4962 upb_alloc *alloc = upb_arena_alloc(a);
4963 upb_array *ret = upb_malloc(alloc, sizeof(upb_array));
4964
4965 if (!ret) {
4966 return NULL;
4967 }
4968
4969 ret->type = type;
4970 ret->data = NULL;
4971 ret->len = 0;
4972 ret->size = 0;
4973 ret->element_size = upb_msgval_sizeof(type);
4974 ret->arena = a;
4975
4976 return ret;
4977}
4978
4979size_t upb_array_size(const upb_array *arr) {
4980 return arr->len;
4981}
4982
4983upb_fieldtype_t upb_array_type(const upb_array *arr) {
4984 return arr->type;
4985}
4986
4987upb_msgval upb_array_get(const upb_array *arr, size_t i) {
4988 UPB_ASSERT(i < arr->len);
4989 return upb_msgval_read(arr->data, i * arr->element_size, arr->element_size);
4990}
4991
4992bool upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
4993 UPB_ASSERT(i <= arr->len);
4994
4995 if (i == arr->len) {
4996 /* Extending the array. */
4997
4998 if (i == arr->size) {
4999 /* Need to reallocate. */
5000 size_t new_size = UPB_MAX(arr->size * 2, 8);
5001 size_t new_bytes = new_size * arr->element_size;
5002 size_t old_bytes = arr->size * arr->element_size;
5003 upb_alloc *alloc = upb_arena_alloc(arr->arena);
5004 upb_msgval *new_data =
5005 upb_realloc(alloc, arr->data, old_bytes, new_bytes);
5006
5007 if (!new_data) {
5008 return false;
5009 }
5010
5011 arr->data = new_data;
5012 arr->size = new_size;
5013 }
5014
5015 arr->len = i + 1;
5016 }
5017
5018 upb_msgval_write(arr->data, i * arr->element_size, val, arr->element_size);
5019 return true;
5020}
5021
5022
5023/** upb_map *******************************************************************/
5024
5025struct upb_map {
5026 upb_fieldtype_t key_type;
5027 upb_fieldtype_t val_type;
5028 /* We may want to optimize this to use inttable where possible, for greater
5029 * efficiency and lower memory footprint. */
5030 upb_strtable strtab;
5031 upb_arena *arena;
5032};
5033
5034static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
5035 const char **out_key, size_t *out_len) {
5036 switch (type) {
5037 case UPB_TYPE_STRING:
5038 /* Point to string data of the input key. */
5039 *out_key = key->str.data;
5040 *out_len = key->str.size;
5041 return;
5042 case UPB_TYPE_BOOL:
5043 case UPB_TYPE_INT32:
5044 case UPB_TYPE_UINT32:
5045 case UPB_TYPE_INT64:
5046 case UPB_TYPE_UINT64:
5047 /* Point to the key itself. XXX: big-endian. */
5048 *out_key = (const char*)key;
5049 *out_len = upb_msgval_sizeof(type);
5050 return;
5051 case UPB_TYPE_BYTES:
5052 case UPB_TYPE_DOUBLE:
5053 case UPB_TYPE_ENUM:
5054 case UPB_TYPE_FLOAT:
5055 case UPB_TYPE_MESSAGE:
5056 break; /* Cannot be a map key. */
5057 }
5058 UPB_UNREACHABLE();
5059}
5060
5061static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
5062 size_t len) {
5063 switch (type) {
5064 case UPB_TYPE_STRING:
5065 return upb_msgval_makestr(key, len);
5066 case UPB_TYPE_BOOL:
5067 case UPB_TYPE_INT32:
5068 case UPB_TYPE_UINT32:
5069 case UPB_TYPE_INT64:
5070 case UPB_TYPE_UINT64:
5071 return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
5072 case UPB_TYPE_BYTES:
5073 case UPB_TYPE_DOUBLE:
5074 case UPB_TYPE_ENUM:
5075 case UPB_TYPE_FLOAT:
5076 case UPB_TYPE_MESSAGE:
5077 break; /* Cannot be a map key. */
5078 }
5079 UPB_UNREACHABLE();
5080}
5081
5082upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
5083 upb_arena *a) {
5084 upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
5085 upb_alloc *alloc = upb_arena_alloc(a);
5086 upb_map *map = upb_malloc(alloc, sizeof(upb_map));
5087
5088 if (!map) {
5089 return NULL;
5090 }
5091
5092 UPB_ASSERT(upb_fieldtype_mapkeyok(ktype));
5093 map->key_type = ktype;
5094 map->val_type = vtype;
5095 map->arena = a;
5096
5097 if (!upb_strtable_init2(&map->strtab, vtabtype, alloc)) {
5098 return NULL;
5099 }
5100
5101 return map;
5102}
5103
5104size_t upb_map_size(const upb_map *map) {
5105 return upb_strtable_count(&map->strtab);
5106}
5107
5108upb_fieldtype_t upb_map_keytype(const upb_map *map) {
5109 return map->key_type;
5110}
5111
5112upb_fieldtype_t upb_map_valuetype(const upb_map *map) {
5113 return map->val_type;
5114}
5115
5116bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
5117 upb_value tabval;
5118 const char *key_str;
5119 size_t key_len;
5120 bool ret;
5121
5122 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
5123 ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
5124 if (ret) {
5125 memcpy(val, &tabval, sizeof(tabval));
5126 }
5127
5128 return ret;
5129}
5130
5131bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
5132 upb_msgval *removed) {
5133 const char *key_str;
5134 size_t key_len;
5135 upb_value tabval = upb_toval(val);
5136 upb_value removedtabval;
5137 upb_alloc *a = upb_arena_alloc(map->arena);
5138
5139 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
5140
5141 /* TODO(haberman): add overwrite operation to minimize number of lookups. */
5142 if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
5143 upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
5144 memcpy(&removed, &removedtabval, sizeof(removed));
5145 }
5146
5147 return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
5148}
5149
5150bool upb_map_del(upb_map *map, upb_msgval key) {
5151 const char *key_str;
5152 size_t key_len;
5153 upb_alloc *a = upb_arena_alloc(map->arena);
5154
5155 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
5156 return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
5157}
5158
5159
5160/** upb_mapiter ***************************************************************/
5161
5162struct upb_mapiter {
5163 upb_strtable_iter iter;
5164 upb_fieldtype_t key_type;
5165};
5166
5167size_t upb_mapiter_sizeof() {
5168 return sizeof(upb_mapiter);
5169}
5170
5171void upb_mapiter_begin(upb_mapiter *i, const upb_map *map) {
5172 upb_strtable_begin(&i->iter, &map->strtab);
5173 i->key_type = map->key_type;
5174}
5175
5176upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a) {
5177 upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
5178
5179 if (!ret) {
5180 return NULL;
5181 }
5182
5183 upb_mapiter_begin(ret, t);
5184 return ret;
5185}
5186
5187void upb_mapiter_free(upb_mapiter *i, upb_alloc *a) {
5188 upb_free(a, i);
5189}
5190
5191void upb_mapiter_next(upb_mapiter *i) {
5192 upb_strtable_next(&i->iter);
5193}
5194
5195bool upb_mapiter_done(const upb_mapiter *i) {
5196 return upb_strtable_done(&i->iter);
5197}
5198
5199upb_msgval upb_mapiter_key(const upb_mapiter *i) {
5200 return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
5201 upb_strtable_iter_keylength(&i->iter));
5202}
5203
5204upb_msgval upb_mapiter_value(const upb_mapiter *i) {
5205 return upb_msgval_fromval(upb_strtable_iter_value(&i->iter));
5206}
5207
5208void upb_mapiter_setdone(upb_mapiter *i) {
5209 upb_strtable_iter_setdone(&i->iter);
5210}
5211
5212bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
5213 return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
5214}
5215
5216
5217static bool is_power_of_two(size_t val) {
5218 return (val & (val - 1)) == 0;
5219}
5220
5221/* Align up to the given power of 2. */
5222static size_t align_up(size_t val, size_t align) {
5223 UPB_ASSERT(is_power_of_two(align));
5224 return (val + align - 1) & ~(align - 1);
5225}
5226
5227static size_t div_round_up(size_t n, size_t d) {
5228 return (n + d - 1) / d;
5229}
5230
5231static size_t upb_msgval_sizeof2(upb_fieldtype_t type) {
5232 switch (type) {
5233 case UPB_TYPE_DOUBLE:
5234 case UPB_TYPE_INT64:
5235 case UPB_TYPE_UINT64:
5236 return 8;
5237 case UPB_TYPE_ENUM:
5238 case UPB_TYPE_INT32:
5239 case UPB_TYPE_UINT32:
5240 case UPB_TYPE_FLOAT:
5241 return 4;
5242 case UPB_TYPE_BOOL:
5243 return 1;
5244 case UPB_TYPE_MESSAGE:
5245 return sizeof(void*);
5246 case UPB_TYPE_BYTES:
5247 case UPB_TYPE_STRING:
Paul Yang57b65972019-03-19 22:27:13 -07005248 return sizeof(upb_strview);
Paul Yang9bda1f12018-09-22 18:57:43 -07005249 }
5250 UPB_UNREACHABLE();
5251}
5252
5253static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
5254 if (upb_fielddef_isseq(f)) {
5255 return sizeof(void*);
5256 } else {
5257 return upb_msgval_sizeof2(upb_fielddef_type(f));
5258 }
5259}
5260
5261
5262/** upb_msglayout *************************************************************/
5263
5264static void upb_msglayout_free(upb_msglayout *l) {
5265 upb_gfree(l);
5266}
5267
5268static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
5269 size_t ret;
5270
5271 l->size = align_up(l->size, size);
5272 ret = l->size;
5273 l->size += size;
5274 return ret;
5275}
5276
5277static bool upb_msglayout_init(const upb_msgdef *m,
5278 upb_msglayout *l,
5279 upb_msgfactory *factory) {
5280 upb_msg_field_iter it;
5281 upb_msg_oneof_iter oit;
5282 size_t hasbit;
5283 size_t submsg_count = 0;
5284 const upb_msglayout **submsgs;
5285 upb_msglayout_field *fields;
5286
5287 for (upb_msg_field_begin(&it, m);
5288 !upb_msg_field_done(&it);
5289 upb_msg_field_next(&it)) {
5290 const upb_fielddef* f = upb_msg_iter_field(&it);
5291 if (upb_fielddef_issubmsg(f)) {
5292 submsg_count++;
5293 }
5294 }
5295
5296 memset(l, 0, sizeof(*l));
5297
5298 fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
5299 submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
5300
5301 if ((!fields && upb_msgdef_numfields(m)) ||
5302 (!submsgs && submsg_count)) {
5303 /* OOM. */
5304 upb_gfree(fields);
5305 upb_gfree(submsgs);
5306 return false;
5307 }
5308
5309 l->field_count = upb_msgdef_numfields(m);
5310 l->fields = fields;
5311 l->submsgs = submsgs;
5312
5313 /* Allocate data offsets in three stages:
5314 *
5315 * 1. hasbits.
5316 * 2. regular fields.
5317 * 3. oneof fields.
5318 *
5319 * OPT: There is a lot of room for optimization here to minimize the size.
5320 */
5321
5322 /* Allocate hasbits and set basic field attributes. */
5323 submsg_count = 0;
5324 for (upb_msg_field_begin(&it, m), hasbit = 0;
5325 !upb_msg_field_done(&it);
5326 upb_msg_field_next(&it)) {
5327 const upb_fielddef* f = upb_msg_iter_field(&it);
5328 upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
5329
5330 field->number = upb_fielddef_number(f);
5331 field->descriptortype = upb_fielddef_descriptortype(f);
5332 field->label = upb_fielddef_label(f);
5333
5334 if (upb_fielddef_issubmsg(f)) {
5335 const upb_msglayout *sub_layout =
5336 upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f));
5337 field->submsg_index = submsg_count++;
5338 submsgs[field->submsg_index] = sub_layout;
5339 }
5340
5341 if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
5342 field->presence = (hasbit++);
5343 } else {
5344 field->presence = 0;
5345 }
5346 }
5347
5348 /* Account for space used by hasbits. */
5349 l->size = div_round_up(hasbit, 8);
5350
5351 /* Allocate non-oneof fields. */
5352 for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
5353 upb_msg_field_next(&it)) {
5354 const upb_fielddef* f = upb_msg_iter_field(&it);
5355 size_t field_size = upb_msg_fielddefsize(f);
5356 size_t index = upb_fielddef_index(f);
5357
5358 if (upb_fielddef_containingoneof(f)) {
5359 /* Oneofs are handled separately below. */
5360 continue;
5361 }
5362
5363 fields[index].offset = upb_msglayout_place(l, field_size);
5364 }
5365
5366 /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
5367 * and space for the actual data. */
5368 for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
5369 upb_msg_oneof_next(&oit)) {
5370 const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
5371 upb_oneof_iter fit;
5372
5373 size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
5374 size_t field_size = 0;
5375 uint32_t case_offset;
5376 uint32_t data_offset;
5377
5378 /* Calculate field size: the max of all field sizes. */
5379 for (upb_oneof_begin(&fit, o);
5380 !upb_oneof_done(&fit);
5381 upb_oneof_next(&fit)) {
5382 const upb_fielddef* f = upb_oneof_iter_field(&fit);
5383 field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
5384 }
5385
5386 /* Align and allocate case offset. */
5387 case_offset = upb_msglayout_place(l, case_size);
5388 data_offset = upb_msglayout_place(l, field_size);
5389
5390 for (upb_oneof_begin(&fit, o);
5391 !upb_oneof_done(&fit);
5392 upb_oneof_next(&fit)) {
5393 const upb_fielddef* f = upb_oneof_iter_field(&fit);
5394 fields[upb_fielddef_index(f)].offset = data_offset;
5395 fields[upb_fielddef_index(f)].presence = ~case_offset;
5396 }
5397 }
5398
5399 /* Size of the entire structure should be a multiple of its greatest
5400 * alignment. TODO: track overall alignment for real? */
5401 l->size = align_up(l->size, 8);
5402
5403 return true;
5404}
5405
5406
5407/** upb_msgfactory ************************************************************/
5408
5409struct upb_msgfactory {
5410 const upb_symtab *symtab; /* We own a ref. */
5411 upb_inttable layouts;
5412 upb_inttable mergehandlers;
5413};
5414
5415upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
5416 upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
5417
5418 ret->symtab = symtab;
5419 upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
5420 upb_inttable_init(&ret->mergehandlers, UPB_CTYPE_CONSTPTR);
5421
5422 return ret;
5423}
5424
5425void upb_msgfactory_free(upb_msgfactory *f) {
5426 upb_inttable_iter i;
5427 upb_inttable_begin(&i, &f->layouts);
5428 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5429 upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
5430 upb_msglayout_free(l);
5431 }
5432
5433 upb_inttable_begin(&i, &f->mergehandlers);
5434 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5435 const upb_handlers *h = upb_value_getconstptr(upb_inttable_iter_value(&i));
5436 upb_handlers_unref(h, f);
5437 }
5438
5439 upb_inttable_uninit(&f->layouts);
5440 upb_inttable_uninit(&f->mergehandlers);
5441 upb_gfree(f);
5442}
5443
5444const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
5445 return f->symtab;
5446}
5447
5448const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
5449 const upb_msgdef *m) {
5450 upb_value v;
5451 UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
5452 UPB_ASSERT(!upb_msgdef_mapentry(m));
5453
5454 if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
5455 UPB_ASSERT(upb_value_getptr(v));
5456 return upb_value_getptr(v);
5457 } else {
5458 /* In case of circular dependency, layout has to be inserted first. */
5459 upb_msglayout *l = upb_gmalloc(sizeof(*l));
5460 upb_msgfactory *mutable_f = (void*)f;
5461 upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
5462 UPB_ASSERT(l);
5463 if (!upb_msglayout_init(m, l, f)) {
5464 upb_msglayout_free(l);
5465 }
5466 return l;
5467 }
5468}
Paul Yangc4f2a922019-01-17 10:18:43 -08005469
5470#if UINTPTR_MAX == 0xffffffff
5471#define UPB_SIZE(size32, size64) size32
5472#else
5473#define UPB_SIZE(size32, size64) size64
5474#endif
5475
5476#define UPB_FIELD_AT(msg, fieldtype, offset) \
5477 *(fieldtype*)((const char*)(msg) + offset)
5478
5479#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
5480 UPB_FIELD_AT(msg, int, case_offset) == case_val \
5481 ? UPB_FIELD_AT(msg, fieldtype, offset) \
5482 : default
5483
5484#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
5485 UPB_FIELD_AT(msg, int, case_offset) = case_val; \
5486 UPB_FIELD_AT(msg, fieldtype, offset) = value;
5487
5488#undef UPB_SIZE
5489#undef UPB_FIELD_AT
5490#undef UPB_READ_ONEOF
5491#undef UPB_WRITE_ONEOF
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005492/*
5493** upb::RefCounted Implementation
5494**
5495** Our key invariants are:
5496** 1. reference cycles never span groups
5497** 2. for ref2(to, from), we increment to's count iff group(from) != group(to)
5498**
5499** The previous two are how we avoid leaking cycles. Other important
5500** invariants are:
5501** 3. for mutable objects "from" and "to", if there exists a ref2(to, from)
5502** this implies group(from) == group(to). (In practice, what we implement
5503** is even stronger; "from" and "to" will share a group if there has *ever*
5504** been a ref2(to, from), but all that is necessary for correctness is the
5505** weaker one).
5506** 4. mutable and immutable objects are never in the same group.
5507*/
5508
5509
5510#include <setjmp.h>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005511
5512static void freeobj(upb_refcounted *o);
5513
5514const char untracked_val;
5515const void *UPB_UNTRACKED_REF = &untracked_val;
5516
5517/* arch-specific atomic primitives *******************************************/
5518
5519#ifdef UPB_THREAD_UNSAFE /*---------------------------------------------------*/
5520
5521static void atomic_inc(uint32_t *a) { (*a)++; }
5522static bool atomic_dec(uint32_t *a) { return --(*a) == 0; }
5523
5524#elif defined(__GNUC__) || defined(__clang__) /*------------------------------*/
5525
5526static void atomic_inc(uint32_t *a) { __sync_fetch_and_add(a, 1); }
5527static bool atomic_dec(uint32_t *a) { return __sync_sub_and_fetch(a, 1) == 0; }
5528
5529#elif defined(WIN32) /*-------------------------------------------------------*/
5530
5531#include <Windows.h>
5532
5533static void atomic_inc(upb_atomic_t *a) { InterlockedIncrement(&a->val); }
5534static bool atomic_dec(upb_atomic_t *a) {
5535 return InterlockedDecrement(&a->val) == 0;
5536}
5537
5538#else
5539#error Atomic primitives not defined for your platform/CPU. \
5540 Implement them or compile with UPB_THREAD_UNSAFE.
5541#endif
5542
5543/* All static objects point to this refcount.
5544 * It is special-cased in ref/unref below. */
5545uint32_t static_refcount = -1;
5546
5547/* We can avoid atomic ops for statically-declared objects.
5548 * This is a minor optimization but nice since we can avoid degrading under
5549 * contention in this case. */
5550
5551static void refgroup(uint32_t *group) {
5552 if (group != &static_refcount)
5553 atomic_inc(group);
5554}
5555
5556static bool unrefgroup(uint32_t *group) {
5557 if (group == &static_refcount) {
5558 return false;
5559 } else {
5560 return atomic_dec(group);
5561 }
5562}
5563
5564
5565/* Reference tracking (debug only) ********************************************/
5566
5567#ifdef UPB_DEBUG_REFS
5568
5569#ifdef UPB_THREAD_UNSAFE
5570
5571static void upb_lock() {}
5572static void upb_unlock() {}
5573
5574#else
5575
5576/* User must define functions that lock/unlock a global mutex and link this
5577 * file against them. */
5578void upb_lock();
5579void upb_unlock();
5580
5581#endif
5582
5583/* UPB_DEBUG_REFS mode counts on being able to malloc() memory in some
5584 * code-paths that can normally never fail, like upb_refcounted_ref(). Since
5585 * we have no way to propagage out-of-memory errors back to the user, and since
Paul Yange0e54662016-09-15 11:09:01 -07005586 * these errors can only occur in UPB_DEBUG_REFS mode, we use an allocator that
5587 * immediately aborts on failure (avoiding the global allocator, which might
5588 * inject failures). */
5589
5590#include <stdlib.h>
5591
5592static void *upb_debugrefs_allocfunc(upb_alloc *alloc, void *ptr,
5593 size_t oldsize, size_t size) {
5594 UPB_UNUSED(alloc);
5595 UPB_UNUSED(oldsize);
5596 if (size == 0) {
5597 free(ptr);
5598 return NULL;
5599 } else {
5600 void *ret = realloc(ptr, size);
5601
5602 if (!ret) {
5603 abort();
5604 }
5605
5606 return ret;
5607 }
5608}
5609
5610upb_alloc upb_alloc_debugrefs = {&upb_debugrefs_allocfunc};
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005611
5612typedef struct {
5613 int count; /* How many refs there are (duplicates only allowed for ref2). */
5614 bool is_ref2;
5615} trackedref;
5616
5617static trackedref *trackedref_new(bool is_ref2) {
Paul Yange0e54662016-09-15 11:09:01 -07005618 trackedref *ret = upb_malloc(&upb_alloc_debugrefs, sizeof(*ret));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005619 ret->count = 1;
5620 ret->is_ref2 = is_ref2;
5621 return ret;
5622}
5623
5624static void track(const upb_refcounted *r, const void *owner, bool ref2) {
5625 upb_value v;
5626
Paul Yange0e54662016-09-15 11:09:01 -07005627 UPB_ASSERT(owner);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005628 if (owner == UPB_UNTRACKED_REF) return;
5629
5630 upb_lock();
5631 if (upb_inttable_lookupptr(r->refs, owner, &v)) {
5632 trackedref *ref = upb_value_getptr(v);
5633 /* Since we allow multiple ref2's for the same to/from pair without
5634 * allocating separate memory for each one, we lose the fine-grained
5635 * tracking behavior we get with regular refs. Since ref2s only happen
5636 * inside upb, we'll accept this limitation until/unless there is a really
5637 * difficult upb-internal bug that can't be figured out without it. */
Paul Yange0e54662016-09-15 11:09:01 -07005638 UPB_ASSERT(ref2);
5639 UPB_ASSERT(ref->is_ref2);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005640 ref->count++;
5641 } else {
5642 trackedref *ref = trackedref_new(ref2);
Paul Yange0e54662016-09-15 11:09:01 -07005643 upb_inttable_insertptr2(r->refs, owner, upb_value_ptr(ref),
5644 &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005645 if (ref2) {
5646 /* We know this cast is safe when it is a ref2, because it's coming from
5647 * another refcounted object. */
5648 const upb_refcounted *from = owner;
Paul Yange0e54662016-09-15 11:09:01 -07005649 UPB_ASSERT(!upb_inttable_lookupptr(from->ref2s, r, NULL));
5650 upb_inttable_insertptr2(from->ref2s, r, upb_value_ptr(NULL),
5651 &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005652 }
5653 }
5654 upb_unlock();
5655}
5656
5657static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
5658 upb_value v;
5659 bool found;
5660 trackedref *ref;
5661
Paul Yange0e54662016-09-15 11:09:01 -07005662 UPB_ASSERT(owner);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005663 if (owner == UPB_UNTRACKED_REF) return;
5664
5665 upb_lock();
5666 found = upb_inttable_lookupptr(r->refs, owner, &v);
5667 /* This assert will fail if an owner attempts to release a ref it didn't have. */
Paul Yange0e54662016-09-15 11:09:01 -07005668 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005669 ref = upb_value_getptr(v);
Paul Yange0e54662016-09-15 11:09:01 -07005670 UPB_ASSERT(ref->is_ref2 == ref2);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005671 if (--ref->count == 0) {
5672 free(ref);
5673 upb_inttable_removeptr(r->refs, owner, NULL);
5674 if (ref2) {
5675 /* We know this cast is safe when it is a ref2, because it's coming from
5676 * another refcounted object. */
5677 const upb_refcounted *from = owner;
5678 bool removed = upb_inttable_removeptr(from->ref2s, r, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07005679 UPB_ASSERT(removed);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005680 }
5681 }
5682 upb_unlock();
5683}
5684
5685static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
5686 upb_value v;
5687 bool found;
5688 trackedref *ref;
5689
5690 upb_lock();
5691 found = upb_inttable_lookupptr(r->refs, owner, &v);
Paul Yange0e54662016-09-15 11:09:01 -07005692 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005693 ref = upb_value_getptr(v);
Paul Yange0e54662016-09-15 11:09:01 -07005694 UPB_ASSERT(ref->is_ref2 == ref2);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005695 upb_unlock();
5696}
5697
5698/* Populates the given UPB_CTYPE_INT32 inttable with counts of ref2's that
5699 * originate from the given owner. */
5700static void getref2s(const upb_refcounted *owner, upb_inttable *tab) {
5701 upb_inttable_iter i;
5702
5703 upb_lock();
5704 upb_inttable_begin(&i, owner->ref2s);
5705 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5706 upb_value v;
5707 upb_value count;
5708 trackedref *ref;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005709 bool found;
5710
5711 upb_refcounted *to = (upb_refcounted*)upb_inttable_iter_key(&i);
5712
5713 /* To get the count we need to look in the target's table. */
5714 found = upb_inttable_lookupptr(to->refs, owner, &v);
Paul Yange0e54662016-09-15 11:09:01 -07005715 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005716 ref = upb_value_getptr(v);
5717 count = upb_value_int32(ref->count);
5718
Paul Yange0e54662016-09-15 11:09:01 -07005719 upb_inttable_insertptr2(tab, to, count, &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005720 }
5721 upb_unlock();
5722}
5723
5724typedef struct {
5725 upb_inttable ref2;
5726 const upb_refcounted *obj;
5727} check_state;
5728
5729static void visit_check(const upb_refcounted *obj, const upb_refcounted *subobj,
5730 void *closure) {
5731 check_state *s = closure;
5732 upb_inttable *ref2 = &s->ref2;
5733 upb_value v;
5734 bool removed;
5735 int32_t newcount;
5736
Paul Yange0e54662016-09-15 11:09:01 -07005737 UPB_ASSERT(obj == s->obj);
5738 UPB_ASSERT(subobj);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005739 removed = upb_inttable_removeptr(ref2, subobj, &v);
5740 /* The following assertion will fail if the visit() function visits a subobj
5741 * that it did not have a ref2 on, or visits the same subobj too many times. */
Paul Yange0e54662016-09-15 11:09:01 -07005742 UPB_ASSERT(removed);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005743 newcount = upb_value_getint32(v) - 1;
5744 if (newcount > 0) {
Paul Yange0e54662016-09-15 11:09:01 -07005745 upb_inttable_insert2(ref2, (uintptr_t)subobj, upb_value_int32(newcount),
5746 &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005747 }
5748}
5749
5750static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
5751 void *closure) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005752 /* In DEBUG_REFS mode we know what existing ref2 refs there are, so we know
5753 * exactly the set of nodes that visit() should visit. So we verify visit()'s
5754 * correctness here. */
5755 check_state state;
5756 state.obj = r;
Paul Yange0e54662016-09-15 11:09:01 -07005757 upb_inttable_init2(&state.ref2, UPB_CTYPE_INT32, &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005758 getref2s(r, &state.ref2);
5759
5760 /* This should visit any children in the ref2 table. */
5761 if (r->vtbl->visit) r->vtbl->visit(r, visit_check, &state);
5762
5763 /* This assertion will fail if the visit() function missed any children. */
Paul Yange0e54662016-09-15 11:09:01 -07005764 UPB_ASSERT(upb_inttable_count(&state.ref2) == 0);
5765 upb_inttable_uninit2(&state.ref2, &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005766 if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
5767}
5768
Paul Yange0e54662016-09-15 11:09:01 -07005769static void trackinit(upb_refcounted *r) {
5770 r->refs = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->refs));
5771 r->ref2s = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->ref2s));
5772 upb_inttable_init2(r->refs, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
5773 upb_inttable_init2(r->ref2s, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005774}
5775
5776static void trackfree(const upb_refcounted *r) {
Paul Yange0e54662016-09-15 11:09:01 -07005777 upb_inttable_uninit2(r->refs, &upb_alloc_debugrefs);
5778 upb_inttable_uninit2(r->ref2s, &upb_alloc_debugrefs);
5779 upb_free(&upb_alloc_debugrefs, r->refs);
5780 upb_free(&upb_alloc_debugrefs, r->ref2s);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005781}
5782
5783#else
5784
5785static void track(const upb_refcounted *r, const void *owner, bool ref2) {
5786 UPB_UNUSED(r);
5787 UPB_UNUSED(owner);
5788 UPB_UNUSED(ref2);
5789}
5790
5791static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
5792 UPB_UNUSED(r);
5793 UPB_UNUSED(owner);
5794 UPB_UNUSED(ref2);
5795}
5796
5797static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
5798 UPB_UNUSED(r);
5799 UPB_UNUSED(owner);
5800 UPB_UNUSED(ref2);
5801}
5802
Paul Yange0e54662016-09-15 11:09:01 -07005803static void trackinit(upb_refcounted *r) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005804 UPB_UNUSED(r);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005805}
5806
5807static void trackfree(const upb_refcounted *r) {
5808 UPB_UNUSED(r);
5809}
5810
5811static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
5812 void *closure) {
5813 if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
5814}
5815
5816#endif /* UPB_DEBUG_REFS */
5817
5818
5819/* freeze() *******************************************************************/
5820
5821/* The freeze() operation is by far the most complicated part of this scheme.
5822 * We compute strongly-connected components and then mutate the graph such that
5823 * we preserve the invariants documented at the top of this file. And we must
5824 * handle out-of-memory errors gracefully (without leaving the graph
5825 * inconsistent), which adds to the fun. */
5826
5827/* The state used by the freeze operation (shared across many functions). */
5828typedef struct {
5829 int depth;
5830 int maxdepth;
5831 uint64_t index;
5832 /* Maps upb_refcounted* -> attributes (color, etc). attr layout varies by
5833 * color. */
5834 upb_inttable objattr;
5835 upb_inttable stack; /* stack of upb_refcounted* for Tarjan's algorithm. */
5836 upb_inttable groups; /* array of uint32_t*, malloc'd refcounts for new groups */
5837 upb_status *status;
5838 jmp_buf err;
5839} tarjan;
5840
5841static void release_ref2(const upb_refcounted *obj,
5842 const upb_refcounted *subobj,
5843 void *closure);
5844
5845/* Node attributes -----------------------------------------------------------*/
5846
5847/* After our analysis phase all nodes will be either GRAY or WHITE. */
5848
5849typedef enum {
5850 BLACK = 0, /* Object has not been seen. */
5851 GRAY, /* Object has been found via a refgroup but may not be reachable. */
5852 GREEN, /* Object is reachable and is currently on the Tarjan stack. */
5853 WHITE /* Object is reachable and has been assigned a group (SCC). */
5854} color_t;
5855
5856UPB_NORETURN static void err(tarjan *t) { longjmp(t->err, 1); }
5857UPB_NORETURN static void oom(tarjan *t) {
5858 upb_status_seterrmsg(t->status, "out of memory");
5859 err(t);
5860}
5861
5862static uint64_t trygetattr(const tarjan *t, const upb_refcounted *r) {
5863 upb_value v;
5864 return upb_inttable_lookupptr(&t->objattr, r, &v) ?
5865 upb_value_getuint64(v) : 0;
5866}
5867
5868static uint64_t getattr(const tarjan *t, const upb_refcounted *r) {
5869 upb_value v;
5870 bool found = upb_inttable_lookupptr(&t->objattr, r, &v);
Paul Yange0e54662016-09-15 11:09:01 -07005871 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005872 return upb_value_getuint64(v);
5873}
5874
5875static void setattr(tarjan *t, const upb_refcounted *r, uint64_t attr) {
5876 upb_inttable_removeptr(&t->objattr, r, NULL);
5877 upb_inttable_insertptr(&t->objattr, r, upb_value_uint64(attr));
5878}
5879
5880static color_t color(tarjan *t, const upb_refcounted *r) {
5881 return trygetattr(t, r) & 0x3; /* Color is always stored in the low 2 bits. */
5882}
5883
5884static void set_gray(tarjan *t, const upb_refcounted *r) {
Paul Yange0e54662016-09-15 11:09:01 -07005885 UPB_ASSERT(color(t, r) == BLACK);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005886 setattr(t, r, GRAY);
5887}
5888
5889/* Pushes an obj onto the Tarjan stack and sets it to GREEN. */
5890static void push(tarjan *t, const upb_refcounted *r) {
Paul Yange0e54662016-09-15 11:09:01 -07005891 UPB_ASSERT(color(t, r) == BLACK || color(t, r) == GRAY);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005892 /* This defines the attr layout for the GREEN state. "index" and "lowlink"
5893 * get 31 bits, which is plenty (limit of 2B objects frozen at a time). */
5894 setattr(t, r, GREEN | (t->index << 2) | (t->index << 33));
5895 if (++t->index == 0x80000000) {
5896 upb_status_seterrmsg(t->status, "too many objects to freeze");
5897 err(t);
5898 }
5899 upb_inttable_push(&t->stack, upb_value_ptr((void*)r));
5900}
5901
5902/* Pops an obj from the Tarjan stack and sets it to WHITE, with a ptr to its
5903 * SCC group. */
5904static upb_refcounted *pop(tarjan *t) {
5905 upb_refcounted *r = upb_value_getptr(upb_inttable_pop(&t->stack));
Paul Yange0e54662016-09-15 11:09:01 -07005906 UPB_ASSERT(color(t, r) == GREEN);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005907 /* This defines the attr layout for nodes in the WHITE state.
5908 * Top of group stack is [group, NULL]; we point at group. */
5909 setattr(t, r, WHITE | (upb_inttable_count(&t->groups) - 2) << 8);
5910 return r;
5911}
5912
5913static void tarjan_newgroup(tarjan *t) {
Paul Yange0e54662016-09-15 11:09:01 -07005914 uint32_t *group = upb_gmalloc(sizeof(*group));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005915 if (!group) oom(t);
5916 /* Push group and empty group leader (we'll fill in leader later). */
5917 if (!upb_inttable_push(&t->groups, upb_value_ptr(group)) ||
5918 !upb_inttable_push(&t->groups, upb_value_ptr(NULL))) {
Paul Yange0e54662016-09-15 11:09:01 -07005919 upb_gfree(group);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005920 oom(t);
5921 }
5922 *group = 0;
5923}
5924
5925static uint32_t idx(tarjan *t, const upb_refcounted *r) {
Paul Yange0e54662016-09-15 11:09:01 -07005926 UPB_ASSERT(color(t, r) == GREEN);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005927 return (getattr(t, r) >> 2) & 0x7FFFFFFF;
5928}
5929
5930static uint32_t lowlink(tarjan *t, const upb_refcounted *r) {
5931 if (color(t, r) == GREEN) {
5932 return getattr(t, r) >> 33;
5933 } else {
5934 return UINT32_MAX;
5935 }
5936}
5937
5938static void set_lowlink(tarjan *t, const upb_refcounted *r, uint32_t lowlink) {
Paul Yange0e54662016-09-15 11:09:01 -07005939 UPB_ASSERT(color(t, r) == GREEN);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005940 setattr(t, r, ((uint64_t)lowlink << 33) | (getattr(t, r) & 0x1FFFFFFFF));
5941}
5942
5943static uint32_t *group(tarjan *t, upb_refcounted *r) {
5944 uint64_t groupnum;
5945 upb_value v;
5946 bool found;
5947
Paul Yange0e54662016-09-15 11:09:01 -07005948 UPB_ASSERT(color(t, r) == WHITE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005949 groupnum = getattr(t, r) >> 8;
5950 found = upb_inttable_lookup(&t->groups, groupnum, &v);
Paul Yange0e54662016-09-15 11:09:01 -07005951 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005952 return upb_value_getptr(v);
5953}
5954
5955/* If the group leader for this object's group has not previously been set,
5956 * the given object is assigned to be its leader. */
5957static upb_refcounted *groupleader(tarjan *t, upb_refcounted *r) {
5958 uint64_t leader_slot;
5959 upb_value v;
5960 bool found;
5961
Paul Yange0e54662016-09-15 11:09:01 -07005962 UPB_ASSERT(color(t, r) == WHITE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005963 leader_slot = (getattr(t, r) >> 8) + 1;
5964 found = upb_inttable_lookup(&t->groups, leader_slot, &v);
Paul Yange0e54662016-09-15 11:09:01 -07005965 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07005966 if (upb_value_getptr(v)) {
5967 return upb_value_getptr(v);
5968 } else {
5969 upb_inttable_remove(&t->groups, leader_slot, NULL);
5970 upb_inttable_insert(&t->groups, leader_slot, upb_value_ptr(r));
5971 return r;
5972 }
5973}
5974
5975
5976/* Tarjan's algorithm --------------------------------------------------------*/
5977
5978/* See:
5979 * http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm */
5980static void do_tarjan(const upb_refcounted *obj, tarjan *t);
5981
5982static void tarjan_visit(const upb_refcounted *obj,
5983 const upb_refcounted *subobj,
5984 void *closure) {
5985 tarjan *t = closure;
5986 if (++t->depth > t->maxdepth) {
5987 upb_status_seterrf(t->status, "graph too deep to freeze (%d)", t->maxdepth);
5988 err(t);
5989 } else if (subobj->is_frozen || color(t, subobj) == WHITE) {
5990 /* Do nothing: we don't want to visit or color already-frozen nodes,
5991 * and WHITE nodes have already been assigned a SCC. */
5992 } else if (color(t, subobj) < GREEN) {
5993 /* Subdef has not yet been visited; recurse on it. */
5994 do_tarjan(subobj, t);
5995 set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), lowlink(t, subobj)));
5996 } else if (color(t, subobj) == GREEN) {
5997 /* Subdef is in the stack and hence in the current SCC. */
5998 set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), idx(t, subobj)));
5999 }
6000 --t->depth;
6001}
6002
6003static void do_tarjan(const upb_refcounted *obj, tarjan *t) {
6004 if (color(t, obj) == BLACK) {
6005 /* We haven't seen this object's group; mark the whole group GRAY. */
6006 const upb_refcounted *o = obj;
6007 do { set_gray(t, o); } while ((o = o->next) != obj);
6008 }
6009
6010 push(t, obj);
6011 visit(obj, tarjan_visit, t);
6012 if (lowlink(t, obj) == idx(t, obj)) {
6013 tarjan_newgroup(t);
6014 while (pop(t) != obj)
6015 ;
6016 }
6017}
6018
6019
6020/* freeze() ------------------------------------------------------------------*/
6021
6022static void crossref(const upb_refcounted *r, const upb_refcounted *subobj,
6023 void *_t) {
6024 tarjan *t = _t;
Paul Yange0e54662016-09-15 11:09:01 -07006025 UPB_ASSERT(color(t, r) > BLACK);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006026 if (color(t, subobj) > BLACK && r->group != subobj->group) {
6027 /* Previously this ref was not reflected in subobj->group because they
6028 * were in the same group; now that they are split a ref must be taken. */
6029 refgroup(subobj->group);
6030 }
6031}
6032
6033static bool freeze(upb_refcounted *const*roots, int n, upb_status *s,
6034 int maxdepth) {
6035 volatile bool ret = false;
6036 int i;
6037 upb_inttable_iter iter;
6038
6039 /* We run in two passes so that we can allocate all memory before performing
6040 * any mutation of the input -- this allows us to leave the input unchanged
6041 * in the case of memory allocation failure. */
6042 tarjan t;
6043 t.index = 0;
6044 t.depth = 0;
6045 t.maxdepth = maxdepth;
6046 t.status = s;
6047 if (!upb_inttable_init(&t.objattr, UPB_CTYPE_UINT64)) goto err1;
6048 if (!upb_inttable_init(&t.stack, UPB_CTYPE_PTR)) goto err2;
6049 if (!upb_inttable_init(&t.groups, UPB_CTYPE_PTR)) goto err3;
6050 if (setjmp(t.err) != 0) goto err4;
6051
6052
6053 for (i = 0; i < n; i++) {
6054 if (color(&t, roots[i]) < GREEN) {
6055 do_tarjan(roots[i], &t);
6056 }
6057 }
6058
6059 /* If we've made it this far, no further errors are possible so it's safe to
6060 * mutate the objects without risk of leaving them in an inconsistent state. */
6061 ret = true;
6062
6063 /* The transformation that follows requires care. The preconditions are:
6064 * - all objects in attr map are WHITE or GRAY, and are in mutable groups
6065 * (groups of all mutable objs)
6066 * - no ref2(to, from) refs have incremented count(to) if both "to" and
6067 * "from" are in our attr map (this follows from invariants (2) and (3)) */
6068
6069 /* Pass 1: we remove WHITE objects from their mutable groups, and add them to
6070 * new groups according to the SCC's we computed. These new groups will
6071 * consist of only frozen objects. None will be immediately collectible,
6072 * because WHITE objects are by definition reachable from one of "roots",
6073 * which the caller must own refs on. */
6074 upb_inttable_begin(&iter, &t.objattr);
6075 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
6076 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
6077 /* Since removal from a singly-linked list requires access to the object's
6078 * predecessor, we consider obj->next instead of obj for moving. With the
6079 * while() loop we guarantee that we will visit every node's predecessor.
6080 * Proof:
6081 * 1. every node's predecessor is in our attr map.
6082 * 2. though the loop body may change a node's predecessor, it will only
6083 * change it to be the node we are currently operating on, so with a
6084 * while() loop we guarantee ourselves the chance to remove each node. */
6085 while (color(&t, obj->next) == WHITE &&
6086 group(&t, obj->next) != obj->next->group) {
6087 upb_refcounted *leader;
6088
6089 /* Remove from old group. */
6090 upb_refcounted *move = obj->next;
6091 if (obj == move) {
6092 /* Removing the last object from a group. */
Paul Yange0e54662016-09-15 11:09:01 -07006093 UPB_ASSERT(*obj->group == obj->individual_count);
6094 upb_gfree(obj->group);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006095 } else {
6096 obj->next = move->next;
6097 /* This may decrease to zero; we'll collect GRAY objects (if any) that
6098 * remain in the group in the third pass. */
Paul Yange0e54662016-09-15 11:09:01 -07006099 UPB_ASSERT(*move->group >= move->individual_count);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006100 *move->group -= move->individual_count;
6101 }
6102
6103 /* Add to new group. */
6104 leader = groupleader(&t, move);
6105 if (move == leader) {
6106 /* First object added to new group is its leader. */
6107 move->group = group(&t, move);
6108 move->next = move;
6109 *move->group = move->individual_count;
6110 } else {
6111 /* Group already has at least one object in it. */
Paul Yange0e54662016-09-15 11:09:01 -07006112 UPB_ASSERT(leader->group == group(&t, move));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006113 move->group = group(&t, move);
6114 move->next = leader->next;
6115 leader->next = move;
6116 *move->group += move->individual_count;
6117 }
6118
6119 move->is_frozen = true;
6120 }
6121 }
6122
6123 /* Pass 2: GRAY and WHITE objects "obj" with ref2(to, obj) references must
6124 * increment count(to) if group(obj) != group(to) (which could now be the
6125 * case if "to" was just frozen). */
6126 upb_inttable_begin(&iter, &t.objattr);
6127 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
6128 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
6129 visit(obj, crossref, &t);
6130 }
6131
6132 /* Pass 3: GRAY objects are collected if their group's refcount dropped to
6133 * zero when we removed its white nodes. This can happen if they had only
6134 * been kept alive by virtue of sharing a group with an object that was just
6135 * frozen.
6136 *
6137 * It is important that we do this last, since the GRAY object's free()
6138 * function could call unref2() on just-frozen objects, which will decrement
6139 * refs that were added in pass 2. */
6140 upb_inttable_begin(&iter, &t.objattr);
6141 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
6142 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
6143 if (obj->group == NULL || *obj->group == 0) {
6144 if (obj->group) {
6145 upb_refcounted *o;
6146
6147 /* We eagerly free() the group's count (since we can't easily determine
6148 * the group's remaining size it's the easiest way to ensure it gets
6149 * done). */
Paul Yange0e54662016-09-15 11:09:01 -07006150 upb_gfree(obj->group);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006151
6152 /* Visit to release ref2's (done in a separate pass since release_ref2
6153 * depends on o->group being unmodified so it can test merged()). */
6154 o = obj;
6155 do { visit(o, release_ref2, NULL); } while ((o = o->next) != obj);
6156
6157 /* Mark "group" fields as NULL so we know to free the objects later in
6158 * this loop, but also don't try to delete the group twice. */
6159 o = obj;
6160 do { o->group = NULL; } while ((o = o->next) != obj);
6161 }
6162 freeobj(obj);
6163 }
6164 }
6165
6166err4:
6167 if (!ret) {
6168 upb_inttable_begin(&iter, &t.groups);
6169 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter))
Paul Yange0e54662016-09-15 11:09:01 -07006170 upb_gfree(upb_value_getptr(upb_inttable_iter_value(&iter)));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006171 }
6172 upb_inttable_uninit(&t.groups);
6173err3:
6174 upb_inttable_uninit(&t.stack);
6175err2:
6176 upb_inttable_uninit(&t.objattr);
6177err1:
6178 return ret;
6179}
6180
6181
6182/* Misc internal functions ***************************************************/
6183
6184static bool merged(const upb_refcounted *r, const upb_refcounted *r2) {
6185 return r->group == r2->group;
6186}
6187
6188static void merge(upb_refcounted *r, upb_refcounted *from) {
6189 upb_refcounted *base;
6190 upb_refcounted *tmp;
6191
6192 if (merged(r, from)) return;
6193 *r->group += *from->group;
Paul Yange0e54662016-09-15 11:09:01 -07006194 upb_gfree(from->group);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006195 base = from;
6196
6197 /* Set all refcount pointers in the "from" chain to the merged refcount.
6198 *
6199 * TODO(haberman): this linear algorithm can result in an overall O(n^2) bound
6200 * if the user continuously extends a group by one object. Prevent this by
6201 * using one of the techniques in this paper:
Paul Yange0e54662016-09-15 11:09:01 -07006202 * http://bioinfo.ict.ac.cn/~dbu/AlgorithmCourses/Lectures/Union-Find-Tarjan.pdf */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006203 do { from->group = r->group; } while ((from = from->next) != base);
6204
6205 /* Merge the two circularly linked lists by swapping their next pointers. */
6206 tmp = r->next;
6207 r->next = base->next;
6208 base->next = tmp;
6209}
6210
6211static void unref(const upb_refcounted *r);
6212
6213static void release_ref2(const upb_refcounted *obj,
6214 const upb_refcounted *subobj,
6215 void *closure) {
6216 UPB_UNUSED(closure);
6217 untrack(subobj, obj, true);
6218 if (!merged(obj, subobj)) {
Paul Yange0e54662016-09-15 11:09:01 -07006219 UPB_ASSERT(subobj->is_frozen);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006220 unref(subobj);
6221 }
6222}
6223
6224static void unref(const upb_refcounted *r) {
6225 if (unrefgroup(r->group)) {
6226 const upb_refcounted *o;
6227
Paul Yange0e54662016-09-15 11:09:01 -07006228 upb_gfree(r->group);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006229
6230 /* In two passes, since release_ref2 needs a guarantee that any subobjs
6231 * are alive. */
6232 o = r;
6233 do { visit(o, release_ref2, NULL); } while((o = o->next) != r);
6234
6235 o = r;
6236 do {
6237 const upb_refcounted *next = o->next;
Paul Yange0e54662016-09-15 11:09:01 -07006238 UPB_ASSERT(o->is_frozen || o->individual_count == 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006239 freeobj((upb_refcounted*)o);
6240 o = next;
6241 } while(o != r);
6242 }
6243}
6244
6245static void freeobj(upb_refcounted *o) {
6246 trackfree(o);
6247 o->vtbl->free((upb_refcounted*)o);
6248}
6249
6250
6251/* Public interface ***********************************************************/
6252
6253bool upb_refcounted_init(upb_refcounted *r,
6254 const struct upb_refcounted_vtbl *vtbl,
6255 const void *owner) {
6256#ifndef NDEBUG
6257 /* Endianness check. This is unrelated to upb_refcounted, it's just a
6258 * convenient place to put the check that we can be assured will run for
6259 * basically every program using upb. */
6260 const int x = 1;
6261#ifdef UPB_BIG_ENDIAN
Paul Yange0e54662016-09-15 11:09:01 -07006262 UPB_ASSERT(*(char*)&x != 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006263#else
Paul Yange0e54662016-09-15 11:09:01 -07006264 UPB_ASSERT(*(char*)&x == 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006265#endif
6266#endif
6267
6268 r->next = r;
6269 r->vtbl = vtbl;
6270 r->individual_count = 0;
6271 r->is_frozen = false;
Paul Yange0e54662016-09-15 11:09:01 -07006272 r->group = upb_gmalloc(sizeof(*r->group));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006273 if (!r->group) return false;
6274 *r->group = 0;
Paul Yange0e54662016-09-15 11:09:01 -07006275 trackinit(r);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006276 upb_refcounted_ref(r, owner);
6277 return true;
6278}
6279
6280bool upb_refcounted_isfrozen(const upb_refcounted *r) {
6281 return r->is_frozen;
6282}
6283
6284void upb_refcounted_ref(const upb_refcounted *r, const void *owner) {
6285 track(r, owner, false);
6286 if (!r->is_frozen)
6287 ((upb_refcounted*)r)->individual_count++;
6288 refgroup(r->group);
6289}
6290
6291void upb_refcounted_unref(const upb_refcounted *r, const void *owner) {
6292 untrack(r, owner, false);
6293 if (!r->is_frozen)
6294 ((upb_refcounted*)r)->individual_count--;
6295 unref(r);
6296}
6297
6298void upb_refcounted_ref2(const upb_refcounted *r, upb_refcounted *from) {
Paul Yange0e54662016-09-15 11:09:01 -07006299 UPB_ASSERT(!from->is_frozen); /* Non-const pointer implies this. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006300 track(r, from, true);
6301 if (r->is_frozen) {
6302 refgroup(r->group);
6303 } else {
6304 merge((upb_refcounted*)r, from);
6305 }
6306}
6307
6308void upb_refcounted_unref2(const upb_refcounted *r, upb_refcounted *from) {
Paul Yange0e54662016-09-15 11:09:01 -07006309 UPB_ASSERT(!from->is_frozen); /* Non-const pointer implies this. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006310 untrack(r, from, true);
6311 if (r->is_frozen) {
6312 unref(r);
6313 } else {
Paul Yange0e54662016-09-15 11:09:01 -07006314 UPB_ASSERT(merged(r, from));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006315 }
6316}
6317
6318void upb_refcounted_donateref(
6319 const upb_refcounted *r, const void *from, const void *to) {
Paul Yange0e54662016-09-15 11:09:01 -07006320 UPB_ASSERT(from != to);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006321 if (to != NULL)
6322 upb_refcounted_ref(r, to);
6323 if (from != NULL)
6324 upb_refcounted_unref(r, from);
6325}
6326
6327void upb_refcounted_checkref(const upb_refcounted *r, const void *owner) {
6328 checkref(r, owner, false);
6329}
6330
6331bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
6332 int maxdepth) {
6333 int i;
Paul Yange0e54662016-09-15 11:09:01 -07006334 bool ret;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006335 for (i = 0; i < n; i++) {
Paul Yange0e54662016-09-15 11:09:01 -07006336 UPB_ASSERT(!roots[i]->is_frozen);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006337 }
Paul Yange0e54662016-09-15 11:09:01 -07006338 ret = freeze(roots, n, s, maxdepth);
6339 UPB_ASSERT(!s || ret == upb_ok(s));
6340 return ret;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006341}
6342
6343
Paul Yang5a3405c2017-02-06 12:40:51 -08006344bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink *sink) {
6345 void *subc;
Paul Yange0e54662016-09-15 11:09:01 -07006346 bool ret;
Paul Yang5a3405c2017-02-06 12:40:51 -08006347 upb_bufhandle handle;
6348 upb_bufhandle_init(&handle);
6349 upb_bufhandle_setbuf(&handle, buf, 0);
6350 ret = upb_bytessink_start(sink, len, &subc);
6351 if (ret && len != 0) {
6352 ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len);
Paul Yange0e54662016-09-15 11:09:01 -07006353 }
Paul Yang5a3405c2017-02-06 12:40:51 -08006354 if (ret) {
6355 ret = upb_bytessink_end(sink);
Paul Yange0e54662016-09-15 11:09:01 -07006356 }
Paul Yang5a3405c2017-02-06 12:40:51 -08006357 upb_bufhandle_uninit(&handle);
Paul Yange0e54662016-09-15 11:09:01 -07006358 return ret;
6359}
6360
Paul Yang5a3405c2017-02-06 12:40:51 -08006361struct upb_bufsink {
6362 upb_byteshandler handler;
6363 upb_bytessink sink;
6364 upb_env *env;
6365 char *ptr;
6366 size_t len, size;
6367};
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006368
Paul Yang5a3405c2017-02-06 12:40:51 -08006369static void *upb_bufsink_start(void *_sink, const void *hd, size_t size_hint) {
6370 upb_bufsink *sink = _sink;
6371 UPB_UNUSED(hd);
6372 UPB_UNUSED(size_hint);
6373 sink->len = 0;
6374 return sink;
6375}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006376
Paul Yang5a3405c2017-02-06 12:40:51 -08006377static size_t upb_bufsink_string(void *_sink, const void *hd, const char *ptr,
6378 size_t len, const upb_bufhandle *handle) {
6379 upb_bufsink *sink = _sink;
6380 size_t new_size = sink->size;
6381
6382 UPB_ASSERT(new_size > 0);
6383 UPB_UNUSED(hd);
6384 UPB_UNUSED(handle);
6385
6386 while (sink->len + len > new_size) {
6387 new_size *= 2;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006388 }
Paul Yang5a3405c2017-02-06 12:40:51 -08006389
6390 if (new_size != sink->size) {
6391 sink->ptr = upb_env_realloc(sink->env, sink->ptr, sink->size, new_size);
6392 sink->size = new_size;
6393 }
6394
6395 memcpy(sink->ptr + sink->len, ptr, len);
6396 sink->len += len;
6397
6398 return len;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006399}
6400
Paul Yang5a3405c2017-02-06 12:40:51 -08006401upb_bufsink *upb_bufsink_new(upb_env *env) {
6402 upb_bufsink *sink = upb_env_malloc(env, sizeof(upb_bufsink));
6403 upb_byteshandler_init(&sink->handler);
6404 upb_byteshandler_setstartstr(&sink->handler, upb_bufsink_start, NULL);
6405 upb_byteshandler_setstring(&sink->handler, upb_bufsink_string, NULL);
6406
6407 upb_bytessink_reset(&sink->sink, &sink->handler, sink);
6408
6409 sink->env = env;
6410 sink->size = 32;
6411 sink->ptr = upb_env_malloc(env, sink->size);
6412 sink->len = 0;
6413
6414 return sink;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006415}
6416
Paul Yang5a3405c2017-02-06 12:40:51 -08006417void upb_bufsink_free(upb_bufsink *sink) {
6418 upb_env_free(sink->env, sink->ptr);
6419 upb_env_free(sink->env, sink);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006420}
6421
Paul Yang5a3405c2017-02-06 12:40:51 -08006422upb_bytessink *upb_bufsink_sink(upb_bufsink *sink) {
6423 return &sink->sink;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006424}
6425
Paul Yang5a3405c2017-02-06 12:40:51 -08006426const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len) {
6427 *len = sink->len;
6428 return sink->ptr;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006429}
6430/*
6431** upb_table Implementation
6432**
6433** Implementation is heavily inspired by Lua's ltable.c.
6434*/
6435
6436
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006437#include <string.h>
6438
6439#define UPB_MAXARRSIZE 16 /* 64k. */
6440
6441/* From Chromium. */
6442#define ARRAY_SIZE(x) \
6443 ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
6444
Paul Yange0e54662016-09-15 11:09:01 -07006445static void upb_check_alloc(upb_table *t, upb_alloc *a) {
6446 UPB_UNUSED(t);
6447 UPB_UNUSED(a);
6448 UPB_ASSERT_DEBUGVAR(t->alloc == a);
6449}
6450
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006451static const double MAX_LOAD = 0.85;
6452
6453/* The minimum utilization of the array part of a mixed hash/array table. This
6454 * is a speed/memory-usage tradeoff (though it's not straightforward because of
6455 * cache effects). The lower this is, the more memory we'll use. */
6456static const double MIN_DENSITY = 0.1;
6457
6458bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
6459
6460int log2ceil(uint64_t v) {
6461 int ret = 0;
6462 bool pow2 = is_pow2(v);
6463 while (v >>= 1) ret++;
6464 ret = pow2 ? ret : ret + 1; /* Ceiling. */
6465 return UPB_MIN(UPB_MAXARRSIZE, ret);
6466}
6467
Paul Yange0e54662016-09-15 11:09:01 -07006468char *upb_strdup(const char *s, upb_alloc *a) {
6469 return upb_strdup2(s, strlen(s), a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006470}
6471
Paul Yange0e54662016-09-15 11:09:01 -07006472char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006473 size_t n;
6474 char *p;
6475
6476 /* Prevent overflow errors. */
6477 if (len == SIZE_MAX) return NULL;
6478 /* Always null-terminate, even if binary data; but don't rely on the input to
6479 * have a null-terminating byte since it may be a raw binary buffer. */
6480 n = len + 1;
Paul Yange0e54662016-09-15 11:09:01 -07006481 p = upb_malloc(a, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006482 if (p) {
6483 memcpy(p, s, len);
6484 p[len] = 0;
6485 }
6486 return p;
6487}
6488
6489/* A type to represent the lookup key of either a strtable or an inttable. */
6490typedef union {
6491 uintptr_t num;
6492 struct {
6493 const char *str;
6494 size_t len;
6495 } str;
6496} lookupkey_t;
6497
6498static lookupkey_t strkey2(const char *str, size_t len) {
6499 lookupkey_t k;
6500 k.str.str = str;
6501 k.str.len = len;
6502 return k;
6503}
6504
6505static lookupkey_t intkey(uintptr_t key) {
6506 lookupkey_t k;
6507 k.num = key;
6508 return k;
6509}
6510
6511typedef uint32_t hashfunc_t(upb_tabkey key);
6512typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
6513
6514/* Base table (shared code) ***************************************************/
6515
6516/* For when we need to cast away const. */
6517static upb_tabent *mutable_entries(upb_table *t) {
6518 return (upb_tabent*)t->entries;
6519}
6520
6521static bool isfull(upb_table *t) {
Paul Yange0e54662016-09-15 11:09:01 -07006522 if (upb_table_size(t) == 0) {
6523 return true;
6524 } else {
6525 return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
6526 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006527}
6528
Paul Yange0e54662016-09-15 11:09:01 -07006529static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
6530 upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006531 size_t bytes;
6532
6533 t->count = 0;
6534 t->ctype = ctype;
6535 t->size_lg2 = size_lg2;
6536 t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
Paul Yange0e54662016-09-15 11:09:01 -07006537#ifndef NDEBUG
6538 t->alloc = a;
6539#endif
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006540 bytes = upb_table_size(t) * sizeof(upb_tabent);
6541 if (bytes > 0) {
Paul Yange0e54662016-09-15 11:09:01 -07006542 t->entries = upb_malloc(a, bytes);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006543 if (!t->entries) return false;
6544 memset(mutable_entries(t), 0, bytes);
6545 } else {
6546 t->entries = NULL;
6547 }
6548 return true;
6549}
6550
Paul Yange0e54662016-09-15 11:09:01 -07006551static void uninit(upb_table *t, upb_alloc *a) {
6552 upb_check_alloc(t, a);
6553 upb_free(a, mutable_entries(t));
6554}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006555
6556static upb_tabent *emptyent(upb_table *t) {
6557 upb_tabent *e = mutable_entries(t) + upb_table_size(t);
Paul Yange0e54662016-09-15 11:09:01 -07006558 while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006559}
6560
6561static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
6562 return (upb_tabent*)upb_getentry(t, hash);
6563}
6564
6565static const upb_tabent *findentry(const upb_table *t, lookupkey_t key,
6566 uint32_t hash, eqlfunc_t *eql) {
6567 const upb_tabent *e;
6568
6569 if (t->size_lg2 == 0) return NULL;
6570 e = upb_getentry(t, hash);
6571 if (upb_tabent_isempty(e)) return NULL;
6572 while (1) {
6573 if (eql(e->key, key)) return e;
6574 if ((e = e->next) == NULL) return NULL;
6575 }
6576}
6577
6578static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key,
6579 uint32_t hash, eqlfunc_t *eql) {
6580 return (upb_tabent*)findentry(t, key, hash, eql);
6581}
6582
6583static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
6584 uint32_t hash, eqlfunc_t *eql) {
6585 const upb_tabent *e = findentry(t, key, hash, eql);
6586 if (e) {
6587 if (v) {
6588 _upb_value_setval(v, e->val.val, t->ctype);
6589 }
6590 return true;
6591 } else {
6592 return false;
6593 }
6594}
6595
6596/* The given key must not already exist in the table. */
6597static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
6598 upb_value val, uint32_t hash,
6599 hashfunc_t *hashfunc, eqlfunc_t *eql) {
6600 upb_tabent *mainpos_e;
6601 upb_tabent *our_e;
6602
Paul Yange0e54662016-09-15 11:09:01 -07006603 UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
6604 UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006605
6606 t->count++;
6607 mainpos_e = getentry_mutable(t, hash);
6608 our_e = mainpos_e;
6609
6610 if (upb_tabent_isempty(mainpos_e)) {
6611 /* Our main position is empty; use it. */
6612 our_e->next = NULL;
6613 } else {
6614 /* Collision. */
6615 upb_tabent *new_e = emptyent(t);
6616 /* Head of collider's chain. */
6617 upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
6618 if (chain == mainpos_e) {
6619 /* Existing ent is in its main posisiton (it has the same hash as us, and
6620 * is the head of our chain). Insert to new ent and append to this chain. */
6621 new_e->next = mainpos_e->next;
6622 mainpos_e->next = new_e;
6623 our_e = new_e;
6624 } else {
6625 /* Existing ent is not in its main position (it is a node in some other
6626 * chain). This implies that no existing ent in the table has our hash.
6627 * Evict it (updating its chain) and use its ent for head of our chain. */
6628 *new_e = *mainpos_e; /* copies next. */
6629 while (chain->next != mainpos_e) {
6630 chain = (upb_tabent*)chain->next;
Paul Yange0e54662016-09-15 11:09:01 -07006631 UPB_ASSERT(chain);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006632 }
6633 chain->next = new_e;
6634 our_e = mainpos_e;
6635 our_e->next = NULL;
6636 }
6637 }
6638 our_e->key = tabkey;
6639 our_e->val.val = val.val;
Paul Yange0e54662016-09-15 11:09:01 -07006640 UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006641}
6642
6643static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
6644 upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
6645 upb_tabent *chain = getentry_mutable(t, hash);
6646 if (upb_tabent_isempty(chain)) return false;
6647 if (eql(chain->key, key)) {
6648 /* Element to remove is at the head of its chain. */
6649 t->count--;
Paul Yange0e54662016-09-15 11:09:01 -07006650 if (val) _upb_value_setval(val, chain->val.val, t->ctype);
6651 if (removed) *removed = chain->key;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006652 if (chain->next) {
6653 upb_tabent *move = (upb_tabent*)chain->next;
6654 *chain = *move;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006655 move->key = 0; /* Make the slot empty. */
6656 } else {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006657 chain->key = 0; /* Make the slot empty. */
6658 }
6659 return true;
6660 } else {
6661 /* Element to remove is either in a non-head position or not in the
6662 * table. */
Paul Yange0e54662016-09-15 11:09:01 -07006663 while (chain->next && !eql(chain->next->key, key)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006664 chain = (upb_tabent*)chain->next;
Paul Yange0e54662016-09-15 11:09:01 -07006665 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006666 if (chain->next) {
6667 /* Found element to remove. */
Paul Yange0e54662016-09-15 11:09:01 -07006668 upb_tabent *rm = (upb_tabent*)chain->next;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006669 t->count--;
Paul Yange0e54662016-09-15 11:09:01 -07006670 if (val) _upb_value_setval(val, chain->next->val.val, t->ctype);
6671 if (removed) *removed = rm->key;
6672 rm->key = 0; /* Make the slot empty. */
6673 chain->next = rm->next;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006674 return true;
6675 } else {
Paul Yange0e54662016-09-15 11:09:01 -07006676 /* Element to remove is not in the table. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006677 return false;
6678 }
6679 }
6680}
6681
6682static size_t next(const upb_table *t, size_t i) {
6683 do {
6684 if (++i >= upb_table_size(t))
6685 return SIZE_MAX;
6686 } while(upb_tabent_isempty(&t->entries[i]));
6687
6688 return i;
6689}
6690
6691static size_t begin(const upb_table *t) {
6692 return next(t, -1);
6693}
6694
6695
6696/* upb_strtable ***************************************************************/
6697
6698/* A simple "subclass" of upb_table that only adds a hash function for strings. */
6699
Paul Yange0e54662016-09-15 11:09:01 -07006700static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
Paul Yang9bda1f12018-09-22 18:57:43 -07006701 uint32_t len = (uint32_t) k2.str.len;
Paul Yange0e54662016-09-15 11:09:01 -07006702 char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006703 if (str == NULL) return 0;
Paul Yang9bda1f12018-09-22 18:57:43 -07006704 memcpy(str, &len, sizeof(uint32_t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006705 memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
6706 return (uintptr_t)str;
6707}
6708
6709static uint32_t strhash(upb_tabkey key) {
6710 uint32_t len;
6711 char *str = upb_tabstr(key, &len);
6712 return MurmurHash2(str, len, 0);
6713}
6714
6715static bool streql(upb_tabkey k1, lookupkey_t k2) {
6716 uint32_t len;
6717 char *str = upb_tabstr(k1, &len);
6718 return len == k2.str.len && memcmp(str, k2.str.str, len) == 0;
6719}
6720
Paul Yange0e54662016-09-15 11:09:01 -07006721bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
6722 return init(&t->t, ctype, 2, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006723}
6724
Paul Yange0e54662016-09-15 11:09:01 -07006725void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006726 size_t i;
6727 for (i = 0; i < upb_table_size(&t->t); i++)
Paul Yange0e54662016-09-15 11:09:01 -07006728 upb_free(a, (void*)t->t.entries[i].key);
6729 uninit(&t->t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006730}
6731
Paul Yange0e54662016-09-15 11:09:01 -07006732bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006733 upb_strtable new_table;
6734 upb_strtable_iter i;
6735
Paul Yange0e54662016-09-15 11:09:01 -07006736 upb_check_alloc(&t->t, a);
6737
6738 if (!init(&new_table.t, t->t.ctype, size_lg2, a))
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006739 return false;
6740 upb_strtable_begin(&i, t);
6741 for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
Paul Yange0e54662016-09-15 11:09:01 -07006742 upb_strtable_insert3(
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006743 &new_table,
6744 upb_strtable_iter_key(&i),
6745 upb_strtable_iter_keylength(&i),
Paul Yange0e54662016-09-15 11:09:01 -07006746 upb_strtable_iter_value(&i),
6747 a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006748 }
Paul Yange0e54662016-09-15 11:09:01 -07006749 upb_strtable_uninit2(t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006750 *t = new_table;
6751 return true;
6752}
6753
Paul Yange0e54662016-09-15 11:09:01 -07006754bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
6755 upb_value v, upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006756 lookupkey_t key;
6757 upb_tabkey tabkey;
6758 uint32_t hash;
6759
Paul Yange0e54662016-09-15 11:09:01 -07006760 upb_check_alloc(&t->t, a);
6761
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006762 if (isfull(&t->t)) {
6763 /* Need to resize. New table of double the size, add old elements to it. */
Paul Yange0e54662016-09-15 11:09:01 -07006764 if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006765 return false;
6766 }
6767 }
6768
6769 key = strkey2(k, len);
Paul Yange0e54662016-09-15 11:09:01 -07006770 tabkey = strcopy(key, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006771 if (tabkey == 0) return false;
6772
6773 hash = MurmurHash2(key.str.str, key.str.len, 0);
6774 insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
6775 return true;
6776}
6777
6778bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
6779 upb_value *v) {
6780 uint32_t hash = MurmurHash2(key, len, 0);
6781 return lookup(&t->t, strkey2(key, len), v, hash, &streql);
6782}
6783
Paul Yange0e54662016-09-15 11:09:01 -07006784bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
6785 upb_value *val, upb_alloc *alloc) {
6786 uint32_t hash = MurmurHash2(key, len, 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006787 upb_tabkey tabkey;
6788 if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
Paul Yange0e54662016-09-15 11:09:01 -07006789 upb_free(alloc, (void*)tabkey);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006790 return true;
6791 } else {
6792 return false;
6793 }
6794}
6795
6796/* Iteration */
6797
6798static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
6799 return &i->t->t.entries[i->index];
6800}
6801
6802void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
6803 i->t = t;
6804 i->index = begin(&t->t);
6805}
6806
6807void upb_strtable_next(upb_strtable_iter *i) {
6808 i->index = next(&i->t->t, i->index);
6809}
6810
6811bool upb_strtable_done(const upb_strtable_iter *i) {
6812 return i->index >= upb_table_size(&i->t->t) ||
6813 upb_tabent_isempty(str_tabent(i));
6814}
6815
Paul Yange0e54662016-09-15 11:09:01 -07006816const char *upb_strtable_iter_key(const upb_strtable_iter *i) {
6817 UPB_ASSERT(!upb_strtable_done(i));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006818 return upb_tabstr(str_tabent(i)->key, NULL);
6819}
6820
Paul Yange0e54662016-09-15 11:09:01 -07006821size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006822 uint32_t len;
Paul Yange0e54662016-09-15 11:09:01 -07006823 UPB_ASSERT(!upb_strtable_done(i));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006824 upb_tabstr(str_tabent(i)->key, &len);
6825 return len;
6826}
6827
6828upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
Paul Yange0e54662016-09-15 11:09:01 -07006829 UPB_ASSERT(!upb_strtable_done(i));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006830 return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
6831}
6832
6833void upb_strtable_iter_setdone(upb_strtable_iter *i) {
6834 i->index = SIZE_MAX;
6835}
6836
6837bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
6838 const upb_strtable_iter *i2) {
6839 if (upb_strtable_done(i1) && upb_strtable_done(i2))
6840 return true;
6841 return i1->t == i2->t && i1->index == i2->index;
6842}
6843
6844
6845/* upb_inttable ***************************************************************/
6846
6847/* For inttables we use a hybrid structure where small keys are kept in an
6848 * array and large keys are put in the hash table. */
6849
6850static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
6851
6852static bool inteql(upb_tabkey k1, lookupkey_t k2) {
6853 return k1 == k2.num;
6854}
6855
6856static upb_tabval *mutable_array(upb_inttable *t) {
6857 return (upb_tabval*)t->array;
6858}
6859
6860static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
6861 if (key < t->array_size) {
6862 return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
6863 } else {
6864 upb_tabent *e =
6865 findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
6866 return e ? &e->val : NULL;
6867 }
6868}
6869
6870static const upb_tabval *inttable_val_const(const upb_inttable *t,
6871 uintptr_t key) {
6872 return inttable_val((upb_inttable*)t, key);
6873}
6874
6875size_t upb_inttable_count(const upb_inttable *t) {
6876 return t->t.count + t->array_count;
6877}
6878
6879static void check(upb_inttable *t) {
6880 UPB_UNUSED(t);
6881#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
6882 {
6883 /* This check is very expensive (makes inserts/deletes O(N)). */
6884 size_t count = 0;
6885 upb_inttable_iter i;
6886 upb_inttable_begin(&i, t);
6887 for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
Paul Yange0e54662016-09-15 11:09:01 -07006888 UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006889 }
Paul Yange0e54662016-09-15 11:09:01 -07006890 UPB_ASSERT(count == upb_inttable_count(t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006891 }
6892#endif
6893}
6894
6895bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
Paul Yange0e54662016-09-15 11:09:01 -07006896 size_t asize, int hsize_lg2, upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006897 size_t array_bytes;
6898
Paul Yange0e54662016-09-15 11:09:01 -07006899 if (!init(&t->t, ctype, hsize_lg2, a)) return false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006900 /* Always make the array part at least 1 long, so that we know key 0
6901 * won't be in the hash part, which simplifies things. */
6902 t->array_size = UPB_MAX(1, asize);
6903 t->array_count = 0;
6904 array_bytes = t->array_size * sizeof(upb_value);
Paul Yange0e54662016-09-15 11:09:01 -07006905 t->array = upb_malloc(a, array_bytes);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006906 if (!t->array) {
Paul Yange0e54662016-09-15 11:09:01 -07006907 uninit(&t->t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006908 return false;
6909 }
6910 memset(mutable_array(t), 0xff, array_bytes);
6911 check(t);
6912 return true;
6913}
6914
Paul Yange0e54662016-09-15 11:09:01 -07006915bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
6916 return upb_inttable_sizedinit(t, ctype, 0, 4, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006917}
6918
Paul Yange0e54662016-09-15 11:09:01 -07006919void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
6920 uninit(&t->t, a);
6921 upb_free(a, mutable_array(t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006922}
6923
Paul Yange0e54662016-09-15 11:09:01 -07006924bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
6925 upb_alloc *a) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006926 upb_tabval tabval;
6927 tabval.val = val.val;
Paul Yange0e54662016-09-15 11:09:01 -07006928 UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
6929
6930 upb_check_alloc(&t->t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006931
6932 if (key < t->array_size) {
Paul Yange0e54662016-09-15 11:09:01 -07006933 UPB_ASSERT(!upb_arrhas(t->array[key]));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006934 t->array_count++;
6935 mutable_array(t)[key].val = val.val;
6936 } else {
6937 if (isfull(&t->t)) {
6938 /* Need to resize the hash part, but we re-use the array part. */
6939 size_t i;
6940 upb_table new_table;
Paul Yange0e54662016-09-15 11:09:01 -07006941
6942 if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006943 return false;
Paul Yange0e54662016-09-15 11:09:01 -07006944 }
6945
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006946 for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
6947 const upb_tabent *e = &t->t.entries[i];
6948 uint32_t hash;
6949 upb_value v;
6950
6951 _upb_value_setval(&v, e->val.val, t->t.ctype);
6952 hash = upb_inthash(e->key);
6953 insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
6954 }
6955
Paul Yange0e54662016-09-15 11:09:01 -07006956 UPB_ASSERT(t->t.count == new_table.count);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006957
Paul Yange0e54662016-09-15 11:09:01 -07006958 uninit(&t->t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006959 t->t = new_table;
6960 }
6961 insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
6962 }
6963 check(t);
6964 return true;
6965}
6966
6967bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
6968 const upb_tabval *table_v = inttable_val_const(t, key);
6969 if (!table_v) return false;
6970 if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
6971 return true;
6972}
6973
6974bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) {
6975 upb_tabval *table_v = inttable_val(t, key);
6976 if (!table_v) return false;
6977 table_v->val = val.val;
6978 return true;
6979}
6980
6981bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
6982 bool success;
6983 if (key < t->array_size) {
6984 if (upb_arrhas(t->array[key])) {
6985 upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
6986 t->array_count--;
6987 if (val) {
6988 _upb_value_setval(val, t->array[key].val, t->t.ctype);
6989 }
6990 mutable_array(t)[key] = empty;
6991 success = true;
6992 } else {
6993 success = false;
6994 }
6995 } else {
Paul Yange0e54662016-09-15 11:09:01 -07006996 success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07006997 }
6998 check(t);
6999 return success;
7000}
7001
Paul Yange0e54662016-09-15 11:09:01 -07007002bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
7003 upb_check_alloc(&t->t, a);
7004 return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007005}
7006
7007upb_value upb_inttable_pop(upb_inttable *t) {
7008 upb_value val;
7009 bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val);
Paul Yange0e54662016-09-15 11:09:01 -07007010 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007011 return val;
7012}
7013
Paul Yange0e54662016-09-15 11:09:01 -07007014bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
7015 upb_alloc *a) {
7016 upb_check_alloc(&t->t, a);
7017 return upb_inttable_insert2(t, (uintptr_t)key, val, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007018}
7019
7020bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
7021 upb_value *v) {
7022 return upb_inttable_lookup(t, (uintptr_t)key, v);
7023}
7024
7025bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
7026 return upb_inttable_remove(t, (uintptr_t)key, val);
7027}
7028
Paul Yange0e54662016-09-15 11:09:01 -07007029void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
7030 /* A power-of-two histogram of the table keys. */
7031 size_t counts[UPB_MAXARRSIZE + 1] = {0};
7032
7033 /* The max key in each bucket. */
7034 uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
7035
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007036 upb_inttable_iter i;
Paul Yange0e54662016-09-15 11:09:01 -07007037 size_t arr_count;
7038 int size_lg2;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007039 upb_inttable new_t;
7040
Paul Yange0e54662016-09-15 11:09:01 -07007041 upb_check_alloc(&t->t, a);
7042
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007043 upb_inttable_begin(&i, t);
7044 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
7045 uintptr_t key = upb_inttable_iter_key(&i);
Paul Yange0e54662016-09-15 11:09:01 -07007046 int bucket = log2ceil(key);
7047 max[bucket] = UPB_MAX(max[bucket], key);
7048 counts[bucket]++;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007049 }
7050
Paul Yange0e54662016-09-15 11:09:01 -07007051 /* Find the largest power of two that satisfies the MIN_DENSITY
7052 * definition (while actually having some keys). */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007053 arr_count = upb_inttable_count(t);
7054
Paul Yange0e54662016-09-15 11:09:01 -07007055 for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
7056 if (counts[size_lg2] == 0) {
7057 /* We can halve again without losing any entries. */
7058 continue;
7059 } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
7060 break;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007061 }
Paul Yange0e54662016-09-15 11:09:01 -07007062
7063 arr_count -= counts[size_lg2];
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007064 }
7065
Paul Yange0e54662016-09-15 11:09:01 -07007066 UPB_ASSERT(arr_count <= upb_inttable_count(t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007067
7068 {
7069 /* Insert all elements into new, perfectly-sized table. */
Paul Yange0e54662016-09-15 11:09:01 -07007070 size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
7071 size_t hash_count = upb_inttable_count(t) - arr_count;
7072 size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
7073 size_t hashsize_lg2 = log2ceil(hash_size);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007074
Paul Yange0e54662016-09-15 11:09:01 -07007075 upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007076 upb_inttable_begin(&i, t);
7077 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
7078 uintptr_t k = upb_inttable_iter_key(&i);
Paul Yange0e54662016-09-15 11:09:01 -07007079 upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007080 }
Paul Yange0e54662016-09-15 11:09:01 -07007081 UPB_ASSERT(new_t.array_size == arr_size);
7082 UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007083 }
Paul Yange0e54662016-09-15 11:09:01 -07007084 upb_inttable_uninit2(t, a);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007085 *t = new_t;
7086}
7087
7088/* Iteration. */
7089
7090static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
Paul Yange0e54662016-09-15 11:09:01 -07007091 UPB_ASSERT(!i->array_part);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007092 return &i->t->t.entries[i->index];
7093}
7094
7095static upb_tabval int_arrent(const upb_inttable_iter *i) {
Paul Yange0e54662016-09-15 11:09:01 -07007096 UPB_ASSERT(i->array_part);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007097 return i->t->array[i->index];
7098}
7099
7100void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
7101 i->t = t;
7102 i->index = -1;
7103 i->array_part = true;
7104 upb_inttable_next(i);
7105}
7106
7107void upb_inttable_next(upb_inttable_iter *iter) {
7108 const upb_inttable *t = iter->t;
7109 if (iter->array_part) {
7110 while (++iter->index < t->array_size) {
7111 if (upb_arrhas(int_arrent(iter))) {
7112 return;
7113 }
7114 }
7115 iter->array_part = false;
7116 iter->index = begin(&t->t);
7117 } else {
7118 iter->index = next(&t->t, iter->index);
7119 }
7120}
7121
7122bool upb_inttable_done(const upb_inttable_iter *i) {
7123 if (i->array_part) {
7124 return i->index >= i->t->array_size ||
7125 !upb_arrhas(int_arrent(i));
7126 } else {
7127 return i->index >= upb_table_size(&i->t->t) ||
7128 upb_tabent_isempty(int_tabent(i));
7129 }
7130}
7131
7132uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
Paul Yange0e54662016-09-15 11:09:01 -07007133 UPB_ASSERT(!upb_inttable_done(i));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007134 return i->array_part ? i->index : int_tabent(i)->key;
7135}
7136
7137upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
Paul Yange0e54662016-09-15 11:09:01 -07007138 UPB_ASSERT(!upb_inttable_done(i));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007139 return _upb_value_val(
7140 i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
7141 i->t->t.ctype);
7142}
7143
7144void upb_inttable_iter_setdone(upb_inttable_iter *i) {
7145 i->index = SIZE_MAX;
7146 i->array_part = false;
7147}
7148
7149bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
7150 const upb_inttable_iter *i2) {
7151 if (upb_inttable_done(i1) && upb_inttable_done(i2))
7152 return true;
7153 return i1->t == i2->t && i1->index == i2->index &&
7154 i1->array_part == i2->array_part;
7155}
7156
7157#ifdef UPB_UNALIGNED_READS_OK
7158/* -----------------------------------------------------------------------------
7159 * MurmurHash2, by Austin Appleby (released as public domain).
7160 * Reformatted and C99-ified by Joshua Haberman.
7161 * Note - This code makes a few assumptions about how your machine behaves -
7162 * 1. We can read a 4-byte value from any address without crashing
7163 * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
7164 * And it has a few limitations -
7165 * 1. It will not work incrementally.
7166 * 2. It will not produce the same results on little-endian and big-endian
7167 * machines. */
7168uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed) {
7169 /* 'm' and 'r' are mixing constants generated offline.
7170 * They're not really 'magic', they just happen to work well. */
7171 const uint32_t m = 0x5bd1e995;
7172 const int32_t r = 24;
7173
7174 /* Initialize the hash to a 'random' value */
7175 uint32_t h = seed ^ len;
7176
7177 /* Mix 4 bytes at a time into the hash */
7178 const uint8_t * data = (const uint8_t *)key;
7179 while(len >= 4) {
7180 uint32_t k = *(uint32_t *)data;
7181
7182 k *= m;
7183 k ^= k >> r;
7184 k *= m;
7185
7186 h *= m;
7187 h ^= k;
7188
7189 data += 4;
7190 len -= 4;
7191 }
7192
7193 /* Handle the last few bytes of the input array */
7194 switch(len) {
7195 case 3: h ^= data[2] << 16;
7196 case 2: h ^= data[1] << 8;
7197 case 1: h ^= data[0]; h *= m;
7198 };
7199
7200 /* Do a few final mixes of the hash to ensure the last few
7201 * bytes are well-incorporated. */
7202 h ^= h >> 13;
7203 h *= m;
7204 h ^= h >> 15;
7205
7206 return h;
7207}
7208
7209#else /* !UPB_UNALIGNED_READS_OK */
7210
7211/* -----------------------------------------------------------------------------
7212 * MurmurHashAligned2, by Austin Appleby
7213 * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
7214 * on certain platforms.
7215 * Performance will be lower than MurmurHash2 */
7216
7217#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
7218
7219uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) {
7220 const uint32_t m = 0x5bd1e995;
7221 const int32_t r = 24;
7222 const uint8_t * data = (const uint8_t *)key;
7223 uint32_t h = seed ^ len;
7224 uint8_t align = (uintptr_t)data & 3;
7225
7226 if(align && (len >= 4)) {
7227 /* Pre-load the temp registers */
7228 uint32_t t = 0, d = 0;
7229 int32_t sl;
7230 int32_t sr;
7231
7232 switch(align) {
7233 case 1: t |= data[2] << 16;
7234 case 2: t |= data[1] << 8;
7235 case 3: t |= data[0];
7236 }
7237
7238 t <<= (8 * align);
7239
7240 data += 4-align;
7241 len -= 4-align;
7242
7243 sl = 8 * (4-align);
7244 sr = 8 * align;
7245
7246 /* Mix */
7247
7248 while(len >= 4) {
7249 uint32_t k;
7250
7251 d = *(uint32_t *)data;
7252 t = (t >> sr) | (d << sl);
7253
7254 k = t;
7255
7256 MIX(h,k,m);
7257
7258 t = d;
7259
7260 data += 4;
7261 len -= 4;
7262 }
7263
7264 /* Handle leftover data in temp registers */
7265
7266 d = 0;
7267
7268 if(len >= align) {
7269 uint32_t k;
7270
7271 switch(align) {
7272 case 3: d |= data[2] << 16;
7273 case 2: d |= data[1] << 8;
7274 case 1: d |= data[0];
7275 }
7276
7277 k = (t >> sr) | (d << sl);
7278 MIX(h,k,m);
7279
7280 data += align;
7281 len -= align;
7282
7283 /* ----------
7284 * Handle tail bytes */
7285
7286 switch(len) {
7287 case 3: h ^= data[2] << 16;
7288 case 2: h ^= data[1] << 8;
7289 case 1: h ^= data[0]; h *= m;
7290 };
7291 } else {
7292 switch(len) {
7293 case 3: d |= data[2] << 16;
7294 case 2: d |= data[1] << 8;
7295 case 1: d |= data[0];
7296 case 0: h ^= (t >> sr) | (d << sl); h *= m;
7297 }
7298 }
7299
7300 h ^= h >> 13;
7301 h *= m;
7302 h ^= h >> 15;
7303
7304 return h;
7305 } else {
7306 while(len >= 4) {
7307 uint32_t k = *(uint32_t *)data;
7308
7309 MIX(h,k,m);
7310
7311 data += 4;
7312 len -= 4;
7313 }
7314
7315 /* ----------
7316 * Handle tail bytes */
7317
7318 switch(len) {
7319 case 3: h ^= data[2] << 16;
7320 case 2: h ^= data[1] << 8;
7321 case 1: h ^= data[0]; h *= m;
7322 };
7323
7324 h ^= h >> 13;
7325 h *= m;
7326 h ^= h >> 15;
7327
7328 return h;
7329 }
7330}
7331#undef MIX
7332
7333#endif /* UPB_UNALIGNED_READS_OK */
7334
7335#include <errno.h>
7336#include <stdarg.h>
7337#include <stddef.h>
7338#include <stdint.h>
7339#include <stdio.h>
7340#include <stdlib.h>
7341#include <string.h>
7342
7343bool upb_dumptostderr(void *closure, const upb_status* status) {
7344 UPB_UNUSED(closure);
7345 fprintf(stderr, "%s\n", upb_status_errmsg(status));
7346 return false;
7347}
7348
7349/* Guarantee null-termination and provide ellipsis truncation.
7350 * It may be tempting to "optimize" this by initializing these final
7351 * four bytes up-front and then being careful never to overwrite them,
7352 * this is safer and simpler. */
7353static void nullz(upb_status *status) {
7354 const char *ellipsis = "...";
7355 size_t len = strlen(ellipsis);
Paul Yange0e54662016-09-15 11:09:01 -07007356 UPB_ASSERT(sizeof(status->msg) > len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007357 memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
7358}
7359
Paul Yange0e54662016-09-15 11:09:01 -07007360
7361/* upb_upberr *****************************************************************/
7362
7363upb_errorspace upb_upberr = {"upb error"};
7364
7365void upb_upberr_setoom(upb_status *status) {
7366 status->error_space_ = &upb_upberr;
7367 upb_status_seterrmsg(status, "Out of memory");
7368}
7369
7370
7371/* upb_status *****************************************************************/
7372
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007373void upb_status_clear(upb_status *status) {
7374 if (!status) return;
7375 status->ok_ = true;
7376 status->code_ = 0;
7377 status->msg[0] = '\0';
7378}
7379
7380bool upb_ok(const upb_status *status) { return status->ok_; }
7381
7382upb_errorspace *upb_status_errspace(const upb_status *status) {
7383 return status->error_space_;
7384}
7385
7386int upb_status_errcode(const upb_status *status) { return status->code_; }
7387
7388const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
7389
7390void upb_status_seterrmsg(upb_status *status, const char *msg) {
7391 if (!status) return;
7392 status->ok_ = false;
7393 strncpy(status->msg, msg, sizeof(status->msg));
7394 nullz(status);
7395}
7396
7397void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
7398 va_list args;
7399 va_start(args, fmt);
7400 upb_status_vseterrf(status, fmt, args);
7401 va_end(args);
7402}
7403
7404void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
7405 if (!status) return;
7406 status->ok_ = false;
7407 _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
7408 nullz(status);
7409}
7410
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007411void upb_status_copy(upb_status *to, const upb_status *from) {
7412 if (!to) return;
7413 *to = *from;
7414}
Paul Yange0e54662016-09-15 11:09:01 -07007415
7416
7417/* upb_alloc ******************************************************************/
7418
7419static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
7420 size_t size) {
7421 UPB_UNUSED(alloc);
7422 UPB_UNUSED(oldsize);
7423 if (size == 0) {
7424 free(ptr);
7425 return NULL;
7426 } else {
7427 return realloc(ptr, size);
7428 }
7429}
7430
7431upb_alloc upb_alloc_global = {&upb_global_allocfunc};
7432
7433
7434/* upb_arena ******************************************************************/
7435
7436/* Be conservative and choose 16 in case anyone is using SSE. */
7437static const size_t maxalign = 16;
7438
Paul Yang5a3405c2017-02-06 12:40:51 -08007439static size_t align_up_max(size_t size) {
Paul Yange0e54662016-09-15 11:09:01 -07007440 return ((size + maxalign - 1) / maxalign) * maxalign;
7441}
7442
7443typedef struct mem_block {
7444 struct mem_block *next;
7445 size_t size;
7446 size_t used;
7447 bool owned;
7448 /* Data follows. */
7449} mem_block;
7450
7451typedef struct cleanup_ent {
7452 struct cleanup_ent *next;
7453 upb_cleanup_func *cleanup;
7454 void *ud;
7455} cleanup_ent;
7456
7457static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size,
7458 bool owned) {
7459 mem_block *block = ptr;
7460
7461 block->next = a->block_head;
7462 block->size = size;
Paul Yang5a3405c2017-02-06 12:40:51 -08007463 block->used = align_up_max(sizeof(mem_block));
Paul Yange0e54662016-09-15 11:09:01 -07007464 block->owned = owned;
7465
7466 a->block_head = block;
7467
7468 /* TODO(haberman): ASAN poison. */
7469}
7470
7471
7472static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) {
7473 size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block);
7474 mem_block *block = upb_malloc(a->block_alloc, block_size);
7475
7476 if (!block) {
7477 return NULL;
7478 }
7479
7480 upb_arena_addblock(a, block, block_size, true);
7481 a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size);
7482
7483 return block;
7484}
7485
7486static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
7487 size_t size) {
7488 upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
7489 mem_block *block = a->block_head;
7490 void *ret;
7491
7492 if (size == 0) {
7493 return NULL; /* We are an arena, don't need individual frees. */
7494 }
7495
Paul Yang5a3405c2017-02-06 12:40:51 -08007496 size = align_up_max(size);
Paul Yange0e54662016-09-15 11:09:01 -07007497
7498 /* TODO(haberman): special-case if this is a realloc of the last alloc? */
7499
7500 if (!block || block->size - block->used < size) {
7501 /* Slow path: have to allocate a new block. */
7502 block = upb_arena_allocblock(a, size);
7503
7504 if (!block) {
7505 return NULL; /* Out of memory. */
7506 }
7507 }
7508
7509 ret = (char*)block + block->used;
7510 block->used += size;
7511
7512 if (oldsize > 0) {
7513 memcpy(ret, ptr, oldsize); /* Preserve existing data. */
7514 }
7515
7516 /* TODO(haberman): ASAN unpoison. */
7517
7518 a->bytes_allocated += size;
7519 return ret;
7520}
7521
7522/* Public Arena API ***********************************************************/
7523
7524void upb_arena_init(upb_arena *a) {
7525 a->alloc.func = &upb_arena_doalloc;
7526 a->block_alloc = &upb_alloc_global;
7527 a->bytes_allocated = 0;
7528 a->next_block_size = 256;
7529 a->max_block_size = 16384;
7530 a->cleanup_head = NULL;
7531 a->block_head = NULL;
7532}
7533
7534void upb_arena_init2(upb_arena *a, void *mem, size_t size, upb_alloc *alloc) {
7535 upb_arena_init(a);
7536
7537 if (size > sizeof(mem_block)) {
7538 upb_arena_addblock(a, mem, size, false);
7539 }
7540
7541 if (alloc) {
7542 a->block_alloc = alloc;
7543 }
7544}
7545
7546void upb_arena_uninit(upb_arena *a) {
7547 cleanup_ent *ent = a->cleanup_head;
7548 mem_block *block = a->block_head;
7549
7550 while (ent) {
7551 ent->cleanup(ent->ud);
7552 ent = ent->next;
7553 }
7554
7555 /* Must do this after running cleanup functions, because this will delete
7556 * the memory we store our cleanup entries in! */
7557 while (block) {
7558 mem_block *next = block->next;
7559
7560 if (block->owned) {
7561 upb_free(a->block_alloc, block);
7562 }
7563
7564 block = next;
7565 }
Paul Yang5a3405c2017-02-06 12:40:51 -08007566
7567 /* Protect against multiple-uninit. */
7568 a->cleanup_head = NULL;
7569 a->block_head = NULL;
Paul Yange0e54662016-09-15 11:09:01 -07007570}
7571
7572bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud) {
7573 cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent));
7574 if (!ent) {
7575 return false; /* Out of memory. */
7576 }
7577
7578 ent->cleanup = func;
7579 ent->ud = ud;
7580 ent->next = a->cleanup_head;
7581 a->cleanup_head = ent;
7582
7583 return true;
7584}
7585
7586size_t upb_arena_bytesallocated(const upb_arena *a) {
7587 return a->bytes_allocated;
7588}
7589
7590
7591/* Standard error functions ***************************************************/
7592
7593static bool default_err(void *ud, const upb_status *status) {
7594 UPB_UNUSED(ud);
7595 UPB_UNUSED(status);
7596 return false;
7597}
7598
7599static bool write_err_to(void *ud, const upb_status *status) {
7600 upb_status *copy_to = ud;
7601 upb_status_copy(copy_to, status);
7602 return false;
7603}
7604
7605
7606/* upb_env ********************************************************************/
7607
7608void upb_env_initonly(upb_env *e) {
7609 e->ok_ = true;
7610 e->error_func_ = &default_err;
7611 e->error_ud_ = NULL;
7612}
7613
7614void upb_env_init(upb_env *e) {
7615 upb_arena_init(&e->arena_);
7616 upb_env_initonly(e);
7617}
7618
7619void upb_env_init2(upb_env *e, void *mem, size_t n, upb_alloc *alloc) {
7620 upb_arena_init2(&e->arena_, mem, n, alloc);
7621 upb_env_initonly(e);
7622}
7623
7624void upb_env_uninit(upb_env *e) {
7625 upb_arena_uninit(&e->arena_);
7626}
7627
7628void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud) {
7629 e->error_func_ = func;
7630 e->error_ud_ = ud;
7631}
7632
7633void upb_env_reporterrorsto(upb_env *e, upb_status *s) {
7634 e->error_func_ = &write_err_to;
7635 e->error_ud_ = s;
7636}
7637
7638bool upb_env_reporterror(upb_env *e, const upb_status *status) {
7639 e->ok_ = false;
7640 return e->error_func_(e->error_ud_, status);
7641}
7642
7643void *upb_env_malloc(upb_env *e, size_t size) {
7644 return upb_malloc(&e->arena_.alloc, size);
7645}
7646
7647void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
7648 return upb_realloc(&e->arena_.alloc, ptr, oldsize, size);
7649}
7650
7651void upb_env_free(upb_env *e, void *ptr) {
7652 upb_free(&e->arena_.alloc, ptr);
7653}
7654
7655bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
7656 return upb_arena_addcleanup(&e->arena_, func, ud);
7657}
7658
7659size_t upb_env_bytesallocated(const upb_env *e) {
7660 return upb_arena_bytesallocated(&e->arena_);
7661}
7662/* This file was generated by upbc (the upb compiler) from the input
7663 * file:
7664 *
7665 * upb/descriptor/descriptor.proto
7666 *
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007667 * Do not edit -- your changes will be discarded when the file is
7668 * regenerated. */
7669
Paul Yange0e54662016-09-15 11:09:01 -07007670static const upb_msgdef msgs[22];
Paul Yang6f325802017-06-05 00:10:18 -07007671static const upb_fielddef fields[107];
Paul Yange0e54662016-09-15 11:09:01 -07007672static const upb_enumdef enums[5];
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007673static const upb_tabent strentries[236];
Paul Yange0e54662016-09-15 11:09:01 -07007674static const upb_tabent intentries[18];
Paul Yang6f325802017-06-05 00:10:18 -07007675static const upb_tabval arrays[187];
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007676
7677#ifdef UPB_DEBUG_REFS
Paul Yang6f325802017-06-05 00:10:18 -07007678static upb_inttable reftables[268];
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007679#endif
7680
Paul Yange0e54662016-09-15 11:09:01 -07007681static const upb_msgdef msgs[22] = {
Paul Yang9bda1f12018-09-22 18:57:43 -07007682 UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[0], &reftables[1]),
7683 UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[2], &reftables[3]),
7684 UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[4], &reftables[5]),
7685 UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[6], &reftables[7]),
7686 UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[8], &reftables[9]),
7687 UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[10], &reftables[11]),
7688 UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[12], &reftables[13]),
7689 UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[14], &reftables[15]),
7690 UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[16], &reftables[17]),
7691 UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[18], &reftables[19]),
7692 UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[20], &reftables[21]),
7693 UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[22], &reftables[23]),
7694 UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[24], &reftables[25]),
7695 UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[26], &reftables[27]),
7696 UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[28], &reftables[29]),
7697 UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[30], &reftables[31]),
7698 UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[32], &reftables[33]),
7699 UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[34], &reftables[35]),
7700 UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[36], &reftables[37]),
7701 UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[38], &reftables[39]),
7702 UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[40], &reftables[41]),
7703 UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, UPB_WELLKNOWN_UNSPECIFIED, &reftables[42], &reftables[43]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007704};
7705
Paul Yang6f325802017-06-05 00:10:18 -07007706static const upb_fielddef fields[107] = {
Paul Yang60327462017-10-09 12:39:13 -07007707 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 16, 6, {0},&reftables[44], &reftables[45]),
7708 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 7, 1, {0},&reftables[46], &reftables[47]),
7709 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 24, 12, {0},&reftables[48], &reftables[49]),
7710 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 18, 6, {0},&reftables[50], &reftables[51]),
7711 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 14, 4, {0},&reftables[52], &reftables[53]),
7712 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 28, 14, {0},&reftables[54], &reftables[55]),
7713 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 7, 1, {0},&reftables[56], &reftables[57]),
7714 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 17, 7, {0},&reftables[58], &reftables[59]),
7715 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 31, 8, {0},&reftables[60], &reftables[61]),
7716 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 9, 3, {0},&reftables[62], &reftables[63]),
7717 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 7, 1, {0},&reftables[64], &reftables[65]),
7718 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 9, 3, {0},&reftables[66], &reftables[67]),
7719 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 22, 10, {0},&reftables[68], &reftables[69]),
7720 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 7, 1, {0},&reftables[70], &reftables[71]),
7721 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 8, 2, {0},&reftables[72], &reftables[73]),
7722 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 7, 1, {0},&reftables[74], &reftables[75]),
7723 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 12, 4, {0},&reftables[76], &reftables[77]),
7724 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 4, 1, {0},&reftables[78], &reftables[79]),
7725 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 4, 1, {0},&reftables[80], &reftables[81]),
7726 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 14, 1, {0},&reftables[82], &reftables[83]),
7727 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 19, 2, {0},&reftables[84], &reftables[85]),
7728 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 8, 2, {0},&reftables[86], &reftables[87]),
7729 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 25, 4, {0},&reftables[88], &reftables[89]),
7730 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 20, 3, {0},&reftables[90], &reftables[91]),
7731 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 22, 3, {0},&reftables[92], &reftables[93]),
7732 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 13, 0, {0},&reftables[94], &reftables[95]),
7733 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 6, 0, {0},&reftables[96], &reftables[97]),
7734 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 15, 5, {0},&reftables[98], &reftables[99]),
7735 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 7, 1, {0},&reftables[100], &reftables[101]),
7736 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 8, 2, {0},&reftables[102], &reftables[103]),
7737 UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 6, 1, {0},&reftables[104], &reftables[105]),
7738 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 21, 9, {0},&reftables[106], &reftables[107]),
7739 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 19, 7, {0},&reftables[108], &reftables[109]),
7740 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 14, 4, {0},&reftables[110], &reftables[111]),
7741 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 10, 2, {0},&reftables[112], &reftables[113]),
7742 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 7, 1, {0},&reftables[114], &reftables[115]),
7743 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 23, 11, {0},&reftables[116], &reftables[117]),
7744 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 31, 15, {0},&reftables[118], &reftables[119]),
7745 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 21, 9, {0},&reftables[120], &reftables[121]),
7746 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 11, 5, {0},&reftables[122], &reftables[123]),
7747 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 12, 4, {0},&reftables[124], &reftables[125]),
7748 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 10, 4, {0},&reftables[126], &reftables[127]),
7749 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 9, 2, {0},&reftables[128], &reftables[129]),
7750 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 17, 4, {0},&reftables[130], &reftables[131]),
7751 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 6, 0, {0},&reftables[132], &reftables[133]),
7752 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 10, 4, {0},&reftables[134], &reftables[135]),
7753 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 7, 1, {0},&reftables[136], &reftables[137]),
7754 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 11, 0, {0},&reftables[138], &reftables[139]),
7755 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 7, 0, {0},&reftables[140], &reftables[141]),
7756 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 6, 0, {0},&reftables[142], &reftables[143]),
7757 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 5, 1, {0},&reftables[144], &reftables[145]),
7758 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 23, 6, {0},&reftables[146], &reftables[147]),
7759 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 9, 2, {0},&reftables[148], &reftables[149]),
7760 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 9, 2, {0},&reftables[150], &reftables[151]),
7761 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 3, 0, {0},&reftables[152], &reftables[153]),
7762 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 5, 1, {0},&reftables[154], &reftables[155]),
7763 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 5, 1, {0},&reftables[156], &reftables[157]),
7764 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 33, 8, {0},&reftables[158], &reftables[159]),
7765 UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 3, 0, {0},&reftables[160], &reftables[161]),
7766 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 11, 3, {0},&reftables[162], &reftables[163]),
7767 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 16, 1, {0},&reftables[164], &reftables[165]),
7768 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 8, 2, {0},&reftables[166], &reftables[167]),
7769 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 11, 3, {0},&reftables[168], &reftables[169]),
7770 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 8, 2, {0},&reftables[170], &reftables[171]),
7771 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 25, 13, {0},&reftables[172], &reftables[173]),
7772 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 29, 6, {0},&reftables[174], &reftables[175]),
7773 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 20, 8, {0},&reftables[176], &reftables[177]),
7774 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 13, 3, {0},&reftables[178], &reftables[179]),
7775 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 26, 5, {0},&reftables[180], &reftables[181]),
7776 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 21, 4, {0},&reftables[182], &reftables[183]),
7777 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 4, 0, {0},&reftables[184], &reftables[185]),
7778 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 4, 0, {0},&reftables[186], &reftables[187]),
7779 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 8, 1, {0},&reftables[188], &reftables[189]),
7780 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 8, 1, {0},&reftables[190], &reftables[191]),
7781 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 4, 0, {0},&reftables[192], &reftables[193]),
7782 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 11, 3, {0},&reftables[194], &reftables[195]),
7783 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 26, 7, {0},&reftables[196], &reftables[197]),
7784 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 8, 2, {0},&reftables[198], &reftables[199]),
7785 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 5, 0, {0},&reftables[200], &reftables[201]),
7786 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 32, 16, {0},&reftables[202], &reftables[203]),
7787 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 35, 17, {0},&reftables[204], &reftables[205]),
7788 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 10, 2, {0},&reftables[206], &reftables[207]),
7789 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 36, 9, {0},&reftables[208], &reftables[209]),
7790 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 20, 8, {0},&reftables[210], &reftables[211]),
7791 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 38, 9, {0},&reftables[212], &reftables[213]),
7792 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 32, 7, {0},&reftables[214], &reftables[215]),
7793 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 15, 5, {0},&reftables[216], &reftables[217]),
7794 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 17, 2, {0},&reftables[218], &reftables[219]),
7795 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 22, 5, {0},&reftables[220], &reftables[221]),
7796 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 8, 1, {0},&reftables[222], &reftables[223]),
7797 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 3, 0, {0},&reftables[224], &reftables[225]),
7798 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 3, 0, {0},&reftables[226], &reftables[227]),
7799 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 13, 5, {0},&reftables[228], &reftables[229]),
7800 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 40, 11, {0},&reftables[230], &reftables[231]),
7801 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 12, 3, {0},&reftables[232], &reftables[233]),
7802 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 13, 5, {0},&reftables[234], &reftables[235]),
7803 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 14, 6, {0},&reftables[236], &reftables[237]),
7804 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[238], &reftables[239]),
7805 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[240], &reftables[241]),
7806 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[242], &reftables[243]),
7807 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[244], &reftables[245]),
7808 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[246], &reftables[247]),
7809 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[248], &reftables[249]),
7810 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[250], &reftables[251]),
7811 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 7, 0, {0},&reftables[252], &reftables[253]),
7812 UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 12, 6, {0},&reftables[254], &reftables[255]),
7813 UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 39, 10, {0},&reftables[256], &reftables[257]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007814};
7815
Paul Yange0e54662016-09-15 11:09:01 -07007816static const upb_enumdef enums[5] = {
Paul Yang6f325802017-06-05 00:10:18 -07007817 UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[154], 4, 3), 0, &reftables[258], &reftables[259]),
7818 UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[158], 19, 18), 0, &reftables[260], &reftables[261]),
7819 UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[262], &reftables[263]),
7820 UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 3, 3), 0, &reftables[264], &reftables[265]),
7821 UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[183], 4, 3), 0, &reftables[266], &reftables[267]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007822};
7823
7824static const upb_tabent strentries[236] = {
Paul Yange0e54662016-09-15 11:09:01 -07007825 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007826 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007827 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
7828 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007829 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7830 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7831 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007832 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[25]), &strentries[12]},
7833 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[24]), &strentries[14]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007834 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007835 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
7836 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007837 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
7838 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007839 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007840 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]},
Paul Yang6f325802017-06-05 00:10:18 -07007841 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007842 {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
7843 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7844 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007845 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007846 {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007847 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7848 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7849 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007850 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
7851 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
7852 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), &strentries[26]},
7853 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007854 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007855 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
7856 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007857 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007858 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007859 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
7860 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), &strentries[34]},
7861 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007862 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007863 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7864 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7865 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
7866 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL},
7867 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007868 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007869 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7870 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7871 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7872 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007873 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), &strentries[53]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007874 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007875 {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007876 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007877 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007878 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[95]), &strentries[50]},
Paul Yange0e54662016-09-15 11:09:01 -07007879 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007880 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
7881 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007882 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007883 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007884 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7885 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7886 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7887 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007888 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
7889 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL},
7890 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7891 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
7892 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7893 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007894 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007895 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7896 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007897 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007898 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[106]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007899 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007900 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
7901 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007902 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007903 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007904 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7905 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007906 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007907 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
7908 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
7909 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007910 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007911 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007912 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[82]), &strentries[85]},
Paul Yange0e54662016-09-15 11:09:01 -07007913 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7914 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007915 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7916 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7917 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7918 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007919 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007920 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), &strentries[116]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007921 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7922 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7923 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7924 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7925 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007926 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7927 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7928 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL},
7929 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[120]},
7930 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7931 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7932 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007933 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "php_namespace"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[113]},
Paul Yange0e54662016-09-15 11:09:01 -07007934 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7935 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7936 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7937 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]},
Paul Yang6f325802017-06-05 00:10:18 -07007938 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007939 {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]},
7940 {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007941 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007942 {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]},
Paul Yang6f325802017-06-05 00:10:18 -07007943 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007944 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL},
7945 {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
7946 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]},
7947 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "objc_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL},
7948 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "cc_enable_arenas"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL},
7949 {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[128]},
7950 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7951 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7952 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007953 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
7954 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007955 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
7956 {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL},
7957 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7958 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007959 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
7960 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007961 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL},
7962 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7963 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007964 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
7965 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007966 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007967 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7968 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7969 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7970 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007971 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007972 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007973 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007974 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]},
Paul Yange0e54662016-09-15 11:09:01 -07007975 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007976 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]},
7977 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
7978 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07007979 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7980 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7981 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007982 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7983 {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL},
7984 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7985 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7986 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7987 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07007988 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[89]), &strentries[167]},
Paul Yange0e54662016-09-15 11:09:01 -07007989 {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]},
Paul Yang6f325802017-06-05 00:10:18 -07007990 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007991 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]},
7992 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
7993 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
7994 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7995 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07007996 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07007997 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7998 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
7999 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8000 {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008001 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "aggregate_value"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL},
8002 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8003 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8004 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8005 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07008006 {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008007 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
Paul Yang6f325802017-06-05 00:10:18 -07008008 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[92]), &strentries[182]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008009 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8010 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008011 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
8012 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL},
8013 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[190]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008014 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8015 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REPEATED"), UPB_TABVALUE_INT_INIT(3), NULL},
8016 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_OPTIONAL"), UPB_TABVALUE_INT_INIT(1), NULL},
8017 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED64"), UPB_TABVALUE_INT_INIT(6), NULL},
8018 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8019 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8020 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8021 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8022 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_STRING"), UPB_TABVALUE_INT_INIT(9), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008023 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[221]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008024 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_DOUBLE"), UPB_TABVALUE_INT_INIT(1), NULL},
8025 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8026 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT32"), UPB_TABVALUE_INT_INIT(5), NULL},
8027 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED32"), UPB_TABVALUE_INT_INIT(15), NULL},
8028 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED32"), UPB_TABVALUE_INT_INIT(7), NULL},
8029 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008030 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[222]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008031 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8032 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008033 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[219]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008034 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8035 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8036 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8037 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8038 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_ENUM"), UPB_TABVALUE_INT_INIT(14), NULL},
8039 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT32"), UPB_TABVALUE_INT_INIT(13), NULL},
8040 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008041 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[218]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008042 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8043 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED64"), UPB_TABVALUE_INT_INIT(16), NULL},
8044 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_BYTES"), UPB_TABVALUE_INT_INIT(12), NULL},
8045 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT64"), UPB_TABVALUE_INT_INIT(18), NULL},
8046 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_BOOL"), UPB_TABVALUE_INT_INIT(8), NULL},
8047 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_GROUP"), UPB_TABVALUE_INT_INIT(10), NULL},
8048 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT32"), UPB_TABVALUE_INT_INIT(17), NULL},
8049 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8050 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "CORD"), UPB_TABVALUE_INT_INIT(1), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008051 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[225]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008052 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "STRING_PIECE"), UPB_TABVALUE_INT_INIT(2), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008053 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8054 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NORMAL"), UPB_TABVALUE_INT_INIT(0), NULL},
8055 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NUMBER"), UPB_TABVALUE_INT_INIT(2), NULL},
8056 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_STRING"), UPB_TABVALUE_INT_INIT(1), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008057 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "CODE_SIZE"), UPB_TABVALUE_INT_INIT(2), NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008058 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[235]},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008059 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8060 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "LITE_RUNTIME"), UPB_TABVALUE_INT_INIT(3), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008061};
8062
Paul Yange0e54662016-09-15 11:09:01 -07008063static const upb_tabent intentries[18] = {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008064 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07008065 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
8066 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07008067 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008068 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07008069 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008070 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yange0e54662016-09-15 11:09:01 -07008071 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008072 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07008073 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
8074 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
8075 {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008076 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6f325802017-06-05 00:10:18 -07008077 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008078 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07008079 {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008080 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
Paul Yang6b27c1f2017-03-17 11:08:06 -07008081 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008082};
8083
Paul Yang6f325802017-06-05 00:10:18 -07008084static const upb_tabval arrays[187] = {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008085 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008086 UPB_TABVALUE_PTR_INIT(&fields[57]),
Paul Yange0e54662016-09-15 11:09:01 -07008087 UPB_TABVALUE_PTR_INIT(&fields[25]),
8088 UPB_TABVALUE_PTR_INIT(&fields[60]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008089 UPB_TABVALUE_PTR_INIT(&fields[20]),
Paul Yange0e54662016-09-15 11:09:01 -07008090 UPB_TABVALUE_PTR_INIT(&fields[24]),
8091 UPB_TABVALUE_PTR_INIT(&fields[22]),
Paul Yang6f325802017-06-05 00:10:18 -07008092 UPB_TABVALUE_PTR_INIT(&fields[68]),
Paul Yange0e54662016-09-15 11:09:01 -07008093 UPB_TABVALUE_PTR_INIT(&fields[65]),
Paul Yang6f325802017-06-05 00:10:18 -07008094 UPB_TABVALUE_PTR_INIT(&fields[85]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008095 UPB_TABVALUE_PTR_INIT(&fields[84]),
Paul Yange0e54662016-09-15 11:09:01 -07008096 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008097 UPB_TABVALUE_PTR_INIT(&fields[91]),
Paul Yange0e54662016-09-15 11:09:01 -07008098 UPB_TABVALUE_PTR_INIT(&fields[18]),
8099 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008100 UPB_TABVALUE_PTR_INIT(&fields[90]),
Paul Yange0e54662016-09-15 11:09:01 -07008101 UPB_TABVALUE_PTR_INIT(&fields[17]),
8102 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008103 UPB_TABVALUE_PTR_INIT(&fields[52]),
8104 UPB_TABVALUE_PTR_INIT(&fields[104]),
8105 UPB_TABVALUE_PTR_INIT(&fields[73]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008106 UPB_TABVALUE_EMPTY_INIT,
8107 UPB_TABVALUE_EMPTY_INIT,
8108 UPB_TABVALUE_PTR_INIT(&fields[1]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008109 UPB_TABVALUE_PTR_INIT(&fields[14]),
8110 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008111 UPB_TABVALUE_PTR_INIT(&fields[50]),
8112 UPB_TABVALUE_PTR_INIT(&fields[63]),
8113 UPB_TABVALUE_PTR_INIT(&fields[74]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008114 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008115 UPB_TABVALUE_PTR_INIT(&fields[13]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008116 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6b27c1f2017-03-17 11:08:06 -07008117 UPB_TABVALUE_PTR_INIT(&fields[56]),
Paul Yange0e54662016-09-15 11:09:01 -07008118 UPB_TABVALUE_PTR_INIT(&fields[21]),
Paul Yang6f325802017-06-05 00:10:18 -07008119 UPB_TABVALUE_PTR_INIT(&fields[62]),
Paul Yange0e54662016-09-15 11:09:01 -07008120 UPB_TABVALUE_PTR_INIT(&fields[40]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008121 UPB_TABVALUE_PTR_INIT(&fields[95]),
Paul Yang6f325802017-06-05 00:10:18 -07008122 UPB_TABVALUE_PTR_INIT(&fields[96]),
Paul Yange0e54662016-09-15 11:09:01 -07008123 UPB_TABVALUE_PTR_INIT(&fields[7]),
Paul Yang6f325802017-06-05 00:10:18 -07008124 UPB_TABVALUE_PTR_INIT(&fields[70]),
Paul Yange0e54662016-09-15 11:09:01 -07008125 UPB_TABVALUE_PTR_INIT(&fields[66]),
8126 UPB_TABVALUE_PTR_INIT(&fields[38]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008127 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008128 UPB_TABVALUE_PTR_INIT(&fields[6]),
8129 UPB_TABVALUE_PTR_INIT(&fields[77]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008130 UPB_TABVALUE_PTR_INIT(&fields[9]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008131 UPB_TABVALUE_EMPTY_INIT,
8132 UPB_TABVALUE_PTR_INIT(&fields[41]),
Paul Yange0e54662016-09-15 11:09:01 -07008133 UPB_TABVALUE_PTR_INIT(&fields[39]),
8134 UPB_TABVALUE_EMPTY_INIT,
8135 UPB_TABVALUE_EMPTY_INIT,
8136 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008137 UPB_TABVALUE_PTR_INIT(&fields[105]),
Paul Yange0e54662016-09-15 11:09:01 -07008138 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008139 UPB_TABVALUE_PTR_INIT(&fields[51]),
Paul Yange0e54662016-09-15 11:09:01 -07008140 UPB_TABVALUE_PTR_INIT(&fields[76]),
8141 UPB_TABVALUE_PTR_INIT(&fields[8]),
8142 UPB_TABVALUE_PTR_INIT(&fields[47]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008143 UPB_TABVALUE_PTR_INIT(&fields[19]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008144 UPB_TABVALUE_PTR_INIT(&fields[87]),
Paul Yang6f325802017-06-05 00:10:18 -07008145 UPB_TABVALUE_PTR_INIT(&fields[23]),
8146 UPB_TABVALUE_PTR_INIT(&fields[69]),
8147 UPB_TABVALUE_PTR_INIT(&fields[88]),
8148 UPB_TABVALUE_PTR_INIT(&fields[82]),
8149 UPB_TABVALUE_PTR_INIT(&fields[106]),
8150 UPB_TABVALUE_PTR_INIT(&fields[93]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008151 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008152 UPB_TABVALUE_PTR_INIT(&fields[26]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008153 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008154 UPB_TABVALUE_PTR_INIT(&fields[35]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008155 UPB_TABVALUE_EMPTY_INIT,
8156 UPB_TABVALUE_EMPTY_INIT,
8157 UPB_TABVALUE_EMPTY_INIT,
8158 UPB_TABVALUE_EMPTY_INIT,
8159 UPB_TABVALUE_EMPTY_INIT,
8160 UPB_TABVALUE_EMPTY_INIT,
8161 UPB_TABVALUE_PTR_INIT(&fields[34]),
Paul Yange0e54662016-09-15 11:09:01 -07008162 UPB_TABVALUE_PTR_INIT(&fields[67]),
8163 UPB_TABVALUE_PTR_INIT(&fields[33]),
8164 UPB_TABVALUE_PTR_INIT(&fields[27]),
8165 UPB_TABVALUE_EMPTY_INIT,
8166 UPB_TABVALUE_EMPTY_INIT,
8167 UPB_TABVALUE_EMPTY_INIT,
8168 UPB_TABVALUE_EMPTY_INIT,
8169 UPB_TABVALUE_PTR_INIT(&fields[3]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008170 UPB_TABVALUE_PTR_INIT(&fields[32]),
Paul Yang6f325802017-06-05 00:10:18 -07008171 UPB_TABVALUE_PTR_INIT(&fields[83]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008172 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008173 UPB_TABVALUE_PTR_INIT(&fields[31]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008174 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008175 UPB_TABVALUE_EMPTY_INIT,
8176 UPB_TABVALUE_PTR_INIT(&fields[12]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008177 UPB_TABVALUE_EMPTY_INIT,
8178 UPB_TABVALUE_EMPTY_INIT,
8179 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008180 UPB_TABVALUE_PTR_INIT(&fields[36]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008181 UPB_TABVALUE_EMPTY_INIT,
8182 UPB_TABVALUE_EMPTY_INIT,
8183 UPB_TABVALUE_EMPTY_INIT,
8184 UPB_TABVALUE_PTR_INIT(&fields[2]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008185 UPB_TABVALUE_EMPTY_INIT,
8186 UPB_TABVALUE_EMPTY_INIT,
8187 UPB_TABVALUE_EMPTY_INIT,
8188 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008189 UPB_TABVALUE_PTR_INIT(&fields[64]),
8190 UPB_TABVALUE_PTR_INIT(&fields[5]),
8191 UPB_TABVALUE_PTR_INIT(&fields[37]),
8192 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6b27c1f2017-03-17 11:08:06 -07008193 UPB_TABVALUE_PTR_INIT(&fields[79]),
Paul Yang6f325802017-06-05 00:10:18 -07008194 UPB_TABVALUE_PTR_INIT(&fields[80]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008195 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008196 UPB_TABVALUE_PTR_INIT(&fields[46]),
8197 UPB_TABVALUE_PTR_INIT(&fields[61]),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008198 UPB_TABVALUE_PTR_INIT(&fields[11]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008199 UPB_TABVALUE_EMPTY_INIT,
8200 UPB_TABVALUE_EMPTY_INIT,
8201 UPB_TABVALUE_EMPTY_INIT,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008202 UPB_TABVALUE_PTR_INIT(&fields[45]),
8203 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008204 UPB_TABVALUE_PTR_INIT(&fields[55]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008205 UPB_TABVALUE_PTR_INIT(&fields[29]),
Paul Yange0e54662016-09-15 11:09:01 -07008206 UPB_TABVALUE_PTR_INIT(&fields[75]),
Paul Yang6f325802017-06-05 00:10:18 -07008207 UPB_TABVALUE_PTR_INIT(&fields[71]),
Paul Yange0e54662016-09-15 11:09:01 -07008208 UPB_TABVALUE_PTR_INIT(&fields[4]),
Paul Yang6f325802017-06-05 00:10:18 -07008209 UPB_TABVALUE_PTR_INIT(&fields[86]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008210 UPB_TABVALUE_EMPTY_INIT,
8211 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6f325802017-06-05 00:10:18 -07008212 UPB_TABVALUE_PTR_INIT(&fields[54]),
Paul Yange0e54662016-09-15 11:09:01 -07008213 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6b27c1f2017-03-17 11:08:06 -07008214 UPB_TABVALUE_PTR_INIT(&fields[53]),
Paul Yange0e54662016-09-15 11:09:01 -07008215 UPB_TABVALUE_PTR_INIT(&fields[48]),
Paul Yang6f325802017-06-05 00:10:18 -07008216 UPB_TABVALUE_PTR_INIT(&fields[72]),
Paul Yange0e54662016-09-15 11:09:01 -07008217 UPB_TABVALUE_EMPTY_INIT,
8218 UPB_TABVALUE_EMPTY_INIT,
8219 UPB_TABVALUE_PTR_INIT(&fields[44]),
8220 UPB_TABVALUE_EMPTY_INIT,
8221 UPB_TABVALUE_PTR_INIT(&fields[78]),
Paul Yang6f325802017-06-05 00:10:18 -07008222 UPB_TABVALUE_PTR_INIT(&fields[89]),
Paul Yange0e54662016-09-15 11:09:01 -07008223 UPB_TABVALUE_PTR_INIT(&fields[42]),
Paul Yang6f325802017-06-05 00:10:18 -07008224 UPB_TABVALUE_PTR_INIT(&fields[94]),
Paul Yange0e54662016-09-15 11:09:01 -07008225 UPB_TABVALUE_EMPTY_INIT,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008226 UPB_TABVALUE_PTR_INIT(&fields[43]),
Paul Yange0e54662016-09-15 11:09:01 -07008227 UPB_TABVALUE_EMPTY_INIT,
8228 UPB_TABVALUE_EMPTY_INIT,
Paul Yang6b27c1f2017-03-17 11:08:06 -07008229 UPB_TABVALUE_PTR_INIT(&fields[49]),
Paul Yange0e54662016-09-15 11:09:01 -07008230 UPB_TABVALUE_PTR_INIT(&fields[28]),
Paul Yang6f325802017-06-05 00:10:18 -07008231 UPB_TABVALUE_PTR_INIT(&fields[81]),
Paul Yange0e54662016-09-15 11:09:01 -07008232 UPB_TABVALUE_PTR_INIT(&fields[59]),
8233 UPB_TABVALUE_PTR_INIT(&fields[16]),
Paul Yang6f325802017-06-05 00:10:18 -07008234 UPB_TABVALUE_PTR_INIT(&fields[92]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008235 UPB_TABVALUE_PTR_INIT(&fields[0]),
8236 UPB_TABVALUE_EMPTY_INIT,
Paul Yange0e54662016-09-15 11:09:01 -07008237 UPB_TABVALUE_PTR_INIT(&fields[58]),
8238 UPB_TABVALUE_PTR_INIT(&fields[30]),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008239 UPB_TABVALUE_EMPTY_INIT,
8240 UPB_TABVALUE_PTR_INIT("LABEL_OPTIONAL"),
8241 UPB_TABVALUE_PTR_INIT("LABEL_REQUIRED"),
8242 UPB_TABVALUE_PTR_INIT("LABEL_REPEATED"),
8243 UPB_TABVALUE_EMPTY_INIT,
8244 UPB_TABVALUE_PTR_INIT("TYPE_DOUBLE"),
8245 UPB_TABVALUE_PTR_INIT("TYPE_FLOAT"),
8246 UPB_TABVALUE_PTR_INIT("TYPE_INT64"),
8247 UPB_TABVALUE_PTR_INIT("TYPE_UINT64"),
8248 UPB_TABVALUE_PTR_INIT("TYPE_INT32"),
8249 UPB_TABVALUE_PTR_INIT("TYPE_FIXED64"),
8250 UPB_TABVALUE_PTR_INIT("TYPE_FIXED32"),
8251 UPB_TABVALUE_PTR_INIT("TYPE_BOOL"),
8252 UPB_TABVALUE_PTR_INIT("TYPE_STRING"),
8253 UPB_TABVALUE_PTR_INIT("TYPE_GROUP"),
8254 UPB_TABVALUE_PTR_INIT("TYPE_MESSAGE"),
8255 UPB_TABVALUE_PTR_INIT("TYPE_BYTES"),
8256 UPB_TABVALUE_PTR_INIT("TYPE_UINT32"),
8257 UPB_TABVALUE_PTR_INIT("TYPE_ENUM"),
8258 UPB_TABVALUE_PTR_INIT("TYPE_SFIXED32"),
8259 UPB_TABVALUE_PTR_INIT("TYPE_SFIXED64"),
8260 UPB_TABVALUE_PTR_INIT("TYPE_SINT32"),
8261 UPB_TABVALUE_PTR_INIT("TYPE_SINT64"),
8262 UPB_TABVALUE_PTR_INIT("STRING"),
8263 UPB_TABVALUE_PTR_INIT("CORD"),
8264 UPB_TABVALUE_PTR_INIT("STRING_PIECE"),
Paul Yange0e54662016-09-15 11:09:01 -07008265 UPB_TABVALUE_PTR_INIT("JS_NORMAL"),
8266 UPB_TABVALUE_PTR_INIT("JS_STRING"),
8267 UPB_TABVALUE_PTR_INIT("JS_NUMBER"),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008268 UPB_TABVALUE_EMPTY_INIT,
8269 UPB_TABVALUE_PTR_INIT("SPEED"),
8270 UPB_TABVALUE_PTR_INIT("CODE_SIZE"),
8271 UPB_TABVALUE_PTR_INIT("LITE_RUNTIME"),
8272};
8273
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008274#ifdef UPB_DEBUG_REFS
Paul Yang6f325802017-06-05 00:10:18 -07008275static upb_inttable reftables[268] = {
8276 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8277 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
Paul Yang6b27c1f2017-03-17 11:08:06 -07008278 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8279 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
Paul Yange0e54662016-09-15 11:09:01 -07008280 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8281 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8282 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8283 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8284 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8285 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8286 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8287 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8288 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8289 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8290 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8291 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8292 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8293 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8294 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8295 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8296 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8297 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8298 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8299 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8300 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8301 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8302 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8303 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8304 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8305 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8306 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8307 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8308 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8309 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8310 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8311 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8312 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8313 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8314 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8315 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8316 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8317 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8318 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8319 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8320 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8321 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8322 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8323 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8324 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8325 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8326 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8327 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8328 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8329 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8330 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8331 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008332 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8333 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8334 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8335 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8336 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8337 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8338 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8339 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8340 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8341 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8342 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8343 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8344 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8345 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8346 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8347 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8348 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8349 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8350 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8351 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8352 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8353 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8354 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8355 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8356 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8357 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8358 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8359 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8360 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8361 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8362 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8363 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8364 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8365 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8366 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8367 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8368 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8369 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8370 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8371 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8372 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8373 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8374 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8375 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8376 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8377 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8378 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8379 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8380 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8381 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8382 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8383 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8384 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8385 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8386 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8387 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8388 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8389 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8390 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8391 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8392 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8393 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8394 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8395 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8396 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8397 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8398 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8399 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8400 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8401 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8402 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8403 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8404 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8405 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8406 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8407 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8408 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8409 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8410 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8411 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8412 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8413 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8414 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8415 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8416 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8417 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8418 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8419 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8420 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8421 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8422 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8423 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8424 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8425 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8426 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8427 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8428 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8429 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8430 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8431 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8432 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8433 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8434 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8435 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8436 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8437 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8438 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8439 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8440 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8441 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8442 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8443 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8444 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8445 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8446 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8447 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8448 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8449 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8450 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8451 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8452 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8453 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8454 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8455 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8456 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8457 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8458 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8459 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8460 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8461 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8462 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8463 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8464 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8465 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8466 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8467 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8468 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8469 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8470 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8471 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8472 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8473 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8474 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8475 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8476 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8477 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8478 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8479 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8480 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8481 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8482 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8483 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8484 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8485 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8486 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8487 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8488 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8489 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8490 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8491 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8492 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8493 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8494 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8495 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8496 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8497 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8498 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8499 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8500 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8501 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8502 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8503 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8504 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8505 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8506 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8507 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8508 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8509 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8510 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8511 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8512 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8513 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8514 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8515 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8516 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8517 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8518 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8519 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8520 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8521 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8522 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8523 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8524 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8525 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8526 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8527 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8528 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8529 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8530 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8531 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8532 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8533 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8534 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8535 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8536 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8537 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8538 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8539 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8540 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8541 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8542 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8543 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
8544};
8545#endif
8546
Paul Yange0e54662016-09-15 11:09:01 -07008547static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) {
8548 upb_msgdef_ref(m, owner);
8549 return m;
8550}
8551
8552static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) {
8553 upb_enumdef_ref(e, owner);
8554 return e;
8555}
8556
8557/* Public API. */
8558const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner) { return refm(&msgs[0], owner); }
8559const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner) { return refm(&msgs[1], owner); }
8560const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(const void *owner) { return refm(&msgs[2], owner); }
8561const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto_get(const void *owner) { return refm(&msgs[3], owner); }
8562const upb_msgdef *upbdefs_google_protobuf_EnumOptions_get(const void *owner) { return refm(&msgs[4], owner); }
8563const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto_get(const void *owner) { return refm(&msgs[5], owner); }
8564const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions_get(const void *owner) { return refm(&msgs[6], owner); }
8565const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto_get(const void *owner) { return refm(&msgs[7], owner); }
8566const upb_msgdef *upbdefs_google_protobuf_FieldOptions_get(const void *owner) { return refm(&msgs[8], owner); }
8567const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto_get(const void *owner) { return refm(&msgs[9], owner); }
8568const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet_get(const void *owner) { return refm(&msgs[10], owner); }
8569const upb_msgdef *upbdefs_google_protobuf_FileOptions_get(const void *owner) { return refm(&msgs[11], owner); }
8570const upb_msgdef *upbdefs_google_protobuf_MessageOptions_get(const void *owner) { return refm(&msgs[12], owner); }
8571const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto_get(const void *owner) { return refm(&msgs[13], owner); }
8572const upb_msgdef *upbdefs_google_protobuf_MethodOptions_get(const void *owner) { return refm(&msgs[14], owner); }
8573const upb_msgdef *upbdefs_google_protobuf_OneofDescriptorProto_get(const void *owner) { return refm(&msgs[15], owner); }
8574const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto_get(const void *owner) { return refm(&msgs[16], owner); }
8575const upb_msgdef *upbdefs_google_protobuf_ServiceOptions_get(const void *owner) { return refm(&msgs[17], owner); }
8576const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_get(const void *owner) { return refm(&msgs[18], owner); }
8577const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location_get(const void *owner) { return refm(&msgs[19], owner); }
8578const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_get(const void *owner) { return refm(&msgs[20], owner); }
8579const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart_get(const void *owner) { return refm(&msgs[21], owner); }
8580
8581const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label_get(const void *owner) { return refe(&enums[0], owner); }
8582const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type_get(const void *owner) { return refe(&enums[1], owner); }
8583const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType_get(const void *owner) { return refe(&enums[2], owner); }
8584const upb_enumdef *upbdefs_google_protobuf_FieldOptions_JSType_get(const void *owner) { return refe(&enums[3], owner); }
8585const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode_get(const void *owner) { return refe(&enums[4], owner); }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008586/*
8587** XXX: The routines in this file that consume a string do not currently
8588** support having the string span buffers. In the future, as upb_sink and
8589** its buffering/sharing functionality evolve there should be an easy and
8590** idiomatic way of correctly handling this case. For now, we accept this
8591** limitation since we currently only parse descriptors from single strings.
8592*/
8593
8594
8595#include <errno.h>
8596#include <stdlib.h>
8597#include <string.h>
8598
Paul Yange0e54662016-09-15 11:09:01 -07008599/* Compares a NULL-terminated string with a non-NULL-terminated string. */
8600static bool upb_streq(const char *str, const char *buf, size_t n) {
8601 return strlen(str) == n && memcmp(str, buf, n) == 0;
8602}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008603
8604/* We keep a stack of all the messages scopes we are currently in, as well as
8605 * the top-level file scope. This is necessary to correctly qualify the
8606 * definitions that are contained inside. "name" tracks the name of the
8607 * message or package (a bare name -- not qualified by any enclosing scopes). */
8608typedef struct {
8609 char *name;
8610 /* Index of the first def that is under this scope. For msgdefs, the
8611 * msgdef itself is at start-1. */
8612 int start;
Paul Yange0e54662016-09-15 11:09:01 -07008613 uint32_t oneof_start;
8614 uint32_t oneof_index;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008615} upb_descreader_frame;
8616
8617/* The maximum number of nested declarations that are allowed, ie.
8618 * message Foo {
8619 * message Bar {
8620 * message Baz {
8621 * }
8622 * }
8623 * }
8624 *
8625 * This is a resource limit that affects how big our runtime stack can grow.
8626 * TODO: make this a runtime-settable property of the Reader instance. */
8627#define UPB_MAX_MESSAGE_NESTING 64
8628
8629struct upb_descreader {
8630 upb_sink sink;
Paul Yange0e54662016-09-15 11:09:01 -07008631 upb_inttable files;
Paul Yang60327462017-10-09 12:39:13 -07008632 upb_strtable files_by_name;
Paul Yange0e54662016-09-15 11:09:01 -07008633 upb_filedef *file; /* The last file in files. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008634 upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
8635 int stack_len;
Paul Yange0e54662016-09-15 11:09:01 -07008636 upb_inttable oneofs;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008637
8638 uint32_t number;
8639 char *name;
8640 bool saw_number;
8641 bool saw_name;
8642
8643 char *default_string;
8644
8645 upb_fielddef *f;
8646};
8647
Paul Yang5a3405c2017-02-06 12:40:51 -08008648static char *upb_gstrndup(const char *buf, size_t n) {
Paul Yange0e54662016-09-15 11:09:01 -07008649 char *ret = upb_gmalloc(n + 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008650 if (!ret) return NULL;
8651 memcpy(ret, buf, n);
8652 ret[n] = '\0';
8653 return ret;
8654}
8655
8656/* Returns a newly allocated string that joins input strings together, for
8657 * example:
8658 * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
8659 * join("", "Baz") -> "Baz"
8660 * Caller owns a ref on the returned string. */
8661static char *upb_join(const char *base, const char *name) {
8662 if (!base || strlen(base) == 0) {
Paul Yange0e54662016-09-15 11:09:01 -07008663 return upb_gstrdup(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008664 } else {
Paul Yange0e54662016-09-15 11:09:01 -07008665 char *ret = upb_gmalloc(strlen(base) + strlen(name) + 2);
8666 if (!ret) {
8667 return NULL;
8668 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008669 ret[0] = '\0';
8670 strcat(ret, base);
8671 strcat(ret, ".");
8672 strcat(ret, name);
8673 return ret;
8674 }
8675}
8676
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008677/* Qualify the defname for all defs starting with offset "start" with "str". */
Paul Yange0e54662016-09-15 11:09:01 -07008678static bool upb_descreader_qualify(upb_filedef *f, char *str, int32_t start) {
8679 size_t i;
8680 for (i = start; i < upb_filedef_defcount(f); i++) {
8681 upb_def *def = upb_filedef_mutabledef(f, i);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008682 char *name = upb_join(str, upb_def_fullname(def));
Paul Yange0e54662016-09-15 11:09:01 -07008683 if (!name) {
8684 /* Need better logic here; at this point we've qualified some names but
8685 * not others. */
8686 return false;
8687 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008688 upb_def_setfullname(def, name, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07008689 upb_gfree(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008690 }
Paul Yange0e54662016-09-15 11:09:01 -07008691 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008692}
8693
8694
8695/* upb_descreader ************************************************************/
8696
8697static upb_msgdef *upb_descreader_top(upb_descreader *r) {
8698 int index;
Paul Yange0e54662016-09-15 11:09:01 -07008699 UPB_ASSERT(r->stack_len > 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008700 index = r->stack[r->stack_len-1].start - 1;
Paul Yange0e54662016-09-15 11:09:01 -07008701 UPB_ASSERT(index >= 0);
8702 return upb_downcast_msgdef_mutable(upb_filedef_mutabledef(r->file, index));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008703}
8704
8705static upb_def *upb_descreader_last(upb_descreader *r) {
Paul Yange0e54662016-09-15 11:09:01 -07008706 return upb_filedef_mutabledef(r->file, upb_filedef_defcount(r->file) - 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008707}
8708
8709/* Start/end handlers for FileDescriptorProto and DescriptorProto (the two
8710 * entities that have names and can contain sub-definitions. */
8711void upb_descreader_startcontainer(upb_descreader *r) {
8712 upb_descreader_frame *f = &r->stack[r->stack_len++];
Paul Yange0e54662016-09-15 11:09:01 -07008713 f->start = upb_filedef_defcount(r->file);
8714 f->oneof_start = upb_inttable_count(&r->oneofs);
8715 f->oneof_index = 0;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008716 f->name = NULL;
8717}
8718
Paul Yange0e54662016-09-15 11:09:01 -07008719bool upb_descreader_endcontainer(upb_descreader *r) {
8720 upb_descreader_frame *f = &r->stack[r->stack_len - 1];
8721
8722 while (upb_inttable_count(&r->oneofs) > f->oneof_start) {
8723 upb_oneofdef *o = upb_value_getptr(upb_inttable_pop(&r->oneofs));
8724 bool ok = upb_msgdef_addoneof(upb_descreader_top(r), o, &r->oneofs, NULL);
8725 UPB_ASSERT(ok);
8726 }
8727
8728 if (!upb_descreader_qualify(r->file, f->name, f->start)) {
8729 return false;
8730 }
8731 upb_gfree(f->name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008732 f->name = NULL;
Paul Yange0e54662016-09-15 11:09:01 -07008733
8734 r->stack_len--;
8735 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008736}
8737
8738void upb_descreader_setscopename(upb_descreader *r, char *str) {
8739 upb_descreader_frame *f = &r->stack[r->stack_len-1];
Paul Yange0e54662016-09-15 11:09:01 -07008740 upb_gfree(f->name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008741 f->name = str;
8742}
8743
Paul Yange0e54662016-09-15 11:09:01 -07008744static upb_oneofdef *upb_descreader_getoneof(upb_descreader *r,
8745 uint32_t index) {
8746 bool found;
8747 upb_value val;
8748 upb_descreader_frame *f = &r->stack[r->stack_len-1];
8749
8750 /* DescriptorProto messages can be nested, so we will see the nested messages
8751 * between when we see the FieldDescriptorProto and the OneofDescriptorProto.
8752 * We need to preserve the oneofs in between these two things. */
8753 index += f->oneof_start;
8754
8755 while (upb_inttable_count(&r->oneofs) <= index) {
8756 upb_inttable_push(&r->oneofs, upb_value_ptr(upb_oneofdef_new(&r->oneofs)));
8757 }
8758
8759 found = upb_inttable_lookup(&r->oneofs, index, &val);
8760 UPB_ASSERT(found);
8761 return upb_value_getptr(val);
8762}
8763
8764/** Handlers for google.protobuf.FileDescriptorSet. ***************************/
8765
8766static void *fileset_startfile(void *closure, const void *hd) {
8767 upb_descreader *r = closure;
8768 UPB_UNUSED(hd);
8769 r->file = upb_filedef_new(&r->files);
8770 upb_inttable_push(&r->files, upb_value_ptr(r->file));
8771 return r;
8772}
8773
8774/** Handlers for google.protobuf.FileDescriptorProto. *************************/
8775
8776static bool file_start(void *closure, const void *hd) {
8777 upb_descreader *r = closure;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008778 UPB_UNUSED(hd);
8779 upb_descreader_startcontainer(r);
8780 return true;
8781}
8782
Paul Yange0e54662016-09-15 11:09:01 -07008783static bool file_end(void *closure, const void *hd, upb_status *status) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008784 upb_descreader *r = closure;
8785 UPB_UNUSED(hd);
8786 UPB_UNUSED(status);
Paul Yange0e54662016-09-15 11:09:01 -07008787 return upb_descreader_endcontainer(r);
8788}
8789
8790static size_t file_onname(void *closure, const void *hd, const char *buf,
8791 size_t n, const upb_bufhandle *handle) {
8792 upb_descreader *r = closure;
8793 char *name;
8794 bool ok;
8795 UPB_UNUSED(hd);
8796 UPB_UNUSED(handle);
8797
Paul Yang5a3405c2017-02-06 12:40:51 -08008798 name = upb_gstrndup(buf, n);
Paul Yang60327462017-10-09 12:39:13 -07008799 upb_strtable_insert(&r->files_by_name, name, upb_value_ptr(r->file));
Paul Yange0e54662016-09-15 11:09:01 -07008800 /* XXX: see comment at the top of the file. */
8801 ok = upb_filedef_setname(r->file, name, NULL);
8802 upb_gfree(name);
8803 UPB_ASSERT(ok);
8804 return n;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008805}
8806
8807static size_t file_onpackage(void *closure, const void *hd, const char *buf,
8808 size_t n, const upb_bufhandle *handle) {
8809 upb_descreader *r = closure;
Paul Yange0e54662016-09-15 11:09:01 -07008810 char *package;
8811 bool ok;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008812 UPB_UNUSED(hd);
8813 UPB_UNUSED(handle);
Paul Yange0e54662016-09-15 11:09:01 -07008814
Paul Yang5a3405c2017-02-06 12:40:51 -08008815 package = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008816 /* XXX: see comment at the top of the file. */
Paul Yange0e54662016-09-15 11:09:01 -07008817 upb_descreader_setscopename(r, package);
8818 ok = upb_filedef_setpackage(r->file, package, NULL);
8819 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008820 return n;
8821}
8822
Paul Yang6f325802017-06-05 00:10:18 -07008823static void *file_startphpnamespace(void *closure, const void *hd,
8824 size_t size_hint) {
8825 upb_descreader *r = closure;
8826 bool ok;
8827 UPB_UNUSED(hd);
8828 UPB_UNUSED(size_hint);
8829
8830 ok = upb_filedef_setphpnamespace(r->file, "", NULL);
8831 UPB_ASSERT(ok);
8832 return closure;
8833}
8834
8835static size_t file_onphpnamespace(void *closure, const void *hd,
8836 const char *buf, size_t n,
8837 const upb_bufhandle *handle) {
8838 upb_descreader *r = closure;
8839 char *php_namespace;
8840 bool ok;
8841 UPB_UNUSED(hd);
8842 UPB_UNUSED(handle);
8843
8844 php_namespace = upb_gstrndup(buf, n);
8845 ok = upb_filedef_setphpnamespace(r->file, php_namespace, NULL);
8846 upb_gfree(php_namespace);
8847 UPB_ASSERT(ok);
8848 return n;
8849}
8850
Paul Yang6b27c1f2017-03-17 11:08:06 -07008851static size_t file_onphpprefix(void *closure, const void *hd, const char *buf,
8852 size_t n, const upb_bufhandle *handle) {
8853 upb_descreader *r = closure;
8854 char *prefix;
8855 bool ok;
8856 UPB_UNUSED(hd);
8857 UPB_UNUSED(handle);
8858
8859 prefix = upb_gstrndup(buf, n);
8860 ok = upb_filedef_setphpprefix(r->file, prefix, NULL);
8861 upb_gfree(prefix);
8862 UPB_ASSERT(ok);
8863 return n;
8864}
8865
Paul Yange0e54662016-09-15 11:09:01 -07008866static size_t file_onsyntax(void *closure, const void *hd, const char *buf,
8867 size_t n, const upb_bufhandle *handle) {
8868 upb_descreader *r = closure;
8869 bool ok;
8870 UPB_UNUSED(hd);
8871 UPB_UNUSED(handle);
8872 /* XXX: see comment at the top of the file. */
8873 if (upb_streq("proto2", buf, n)) {
8874 ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO2, NULL);
8875 } else if (upb_streq("proto3", buf, n)) {
8876 ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO3, NULL);
8877 } else {
8878 ok = false;
8879 }
8880
8881 UPB_ASSERT(ok);
8882 return n;
8883}
8884
8885static void *file_startmsg(void *closure, const void *hd) {
8886 upb_descreader *r = closure;
8887 upb_msgdef *m = upb_msgdef_new(&m);
8888 bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
8889 UPB_UNUSED(hd);
8890 UPB_ASSERT(ok);
8891 return r;
8892}
8893
8894static void *file_startenum(void *closure, const void *hd) {
8895 upb_descreader *r = closure;
8896 upb_enumdef *e = upb_enumdef_new(&e);
8897 bool ok = upb_filedef_addenum(r->file, e, &e, NULL);
8898 UPB_UNUSED(hd);
8899 UPB_ASSERT(ok);
8900 return r;
8901}
8902
8903static void *file_startext(void *closure, const void *hd) {
8904 upb_descreader *r = closure;
Paul Yange0e54662016-09-15 11:09:01 -07008905 r->f = upb_fielddef_new(r);
Paul Yange0e54662016-09-15 11:09:01 -07008906 UPB_UNUSED(hd);
Paul Yange0e54662016-09-15 11:09:01 -07008907 return r;
8908}
8909
Paul Yang57b65972019-03-19 22:27:13 -07008910static bool file_endext(void *closure, const void *hd) {
8911 /* The current symtab code can't handle extensions, so we just discard
8912 * them for now. */
8913 upb_descreader *r = closure;
8914 upb_fielddef_unref(r->f, r);
8915 UPB_UNUSED(hd);
8916 r->f = NULL;
8917 return true;
8918}
8919
Paul Yang60327462017-10-09 12:39:13 -07008920static size_t file_ondep(void *closure, const void *hd, const char *buf,
8921 size_t n, const upb_bufhandle *handle) {
8922 upb_descreader *r = closure;
8923 upb_value val;
8924 if (upb_strtable_lookup2(&r->files_by_name, buf, n, &val)) {
8925 upb_filedef_adddep(r->file, upb_value_getptr(val));
8926 }
8927 UPB_UNUSED(hd);
8928 UPB_UNUSED(handle);
8929 return n;
8930}
8931
Paul Yange0e54662016-09-15 11:09:01 -07008932/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/
8933
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008934static bool enumval_startmsg(void *closure, const void *hd) {
8935 upb_descreader *r = closure;
8936 UPB_UNUSED(hd);
8937 r->saw_number = false;
8938 r->saw_name = false;
8939 return true;
8940}
8941
8942static size_t enumval_onname(void *closure, const void *hd, const char *buf,
8943 size_t n, const upb_bufhandle *handle) {
8944 upb_descreader *r = closure;
8945 UPB_UNUSED(hd);
8946 UPB_UNUSED(handle);
8947 /* XXX: see comment at the top of the file. */
Paul Yange0e54662016-09-15 11:09:01 -07008948 upb_gfree(r->name);
Paul Yang5a3405c2017-02-06 12:40:51 -08008949 r->name = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008950 r->saw_name = true;
8951 return n;
8952}
8953
8954static bool enumval_onnumber(void *closure, const void *hd, int32_t val) {
8955 upb_descreader *r = closure;
8956 UPB_UNUSED(hd);
8957 r->number = val;
8958 r->saw_number = true;
8959 return true;
8960}
8961
8962static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) {
8963 upb_descreader *r = closure;
8964 upb_enumdef *e;
8965 UPB_UNUSED(hd);
8966
8967 if(!r->saw_number || !r->saw_name) {
8968 upb_status_seterrmsg(status, "Enum value missing name or number.");
8969 return false;
8970 }
8971 e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
8972 upb_enumdef_addval(e, r->name, r->number, status);
Paul Yange0e54662016-09-15 11:09:01 -07008973 upb_gfree(r->name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008974 r->name = NULL;
8975 return true;
8976}
8977
Paul Yange0e54662016-09-15 11:09:01 -07008978/** Handlers for google.protobuf.EnumDescriptorProto. *************************/
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07008979
8980static bool enum_endmsg(void *closure, const void *hd, upb_status *status) {
8981 upb_descreader *r = closure;
8982 upb_enumdef *e;
8983 UPB_UNUSED(hd);
8984
8985 e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
8986 if (upb_def_fullname(upb_descreader_last(r)) == NULL) {
8987 upb_status_seterrmsg(status, "Enum had no name.");
8988 return false;
8989 }
8990 if (upb_enumdef_numvals(e) == 0) {
8991 upb_status_seterrmsg(status, "Enum had no values.");
8992 return false;
8993 }
8994 return true;
8995}
8996
8997static size_t enum_onname(void *closure, const void *hd, const char *buf,
8998 size_t n, const upb_bufhandle *handle) {
8999 upb_descreader *r = closure;
Paul Yang5a3405c2017-02-06 12:40:51 -08009000 char *fullname = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009001 UPB_UNUSED(hd);
9002 UPB_UNUSED(handle);
9003 /* XXX: see comment at the top of the file. */
9004 upb_def_setfullname(upb_descreader_last(r), fullname, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009005 upb_gfree(fullname);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009006 return n;
9007}
9008
Paul Yange0e54662016-09-15 11:09:01 -07009009/** Handlers for google.protobuf.FieldDescriptorProto *************************/
9010
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009011static bool field_startmsg(void *closure, const void *hd) {
9012 upb_descreader *r = closure;
9013 UPB_UNUSED(hd);
Paul Yange0e54662016-09-15 11:09:01 -07009014 UPB_ASSERT(r->f);
9015 upb_gfree(r->default_string);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009016 r->default_string = NULL;
9017
9018 /* fielddefs default to packed, but descriptors default to non-packed. */
9019 upb_fielddef_setpacked(r->f, false);
9020 return true;
9021}
9022
9023/* Converts the default value in string "str" into "d". Passes a ref on str.
9024 * Returns true on success. */
9025static bool parse_default(char *str, upb_fielddef *f) {
9026 bool success = true;
9027 char *end;
9028 switch (upb_fielddef_type(f)) {
9029 case UPB_TYPE_INT32: {
9030 long val = strtol(str, &end, 0);
9031 if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end)
9032 success = false;
9033 else
9034 upb_fielddef_setdefaultint32(f, val);
9035 break;
9036 }
9037 case UPB_TYPE_INT64: {
9038 /* XXX: Need to write our own strtoll, since it's not available in c89. */
9039 long long val = strtol(str, &end, 0);
9040 if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end)
9041 success = false;
9042 else
9043 upb_fielddef_setdefaultint64(f, val);
9044 break;
9045 }
9046 case UPB_TYPE_UINT32: {
9047 unsigned long val = strtoul(str, &end, 0);
9048 if (val > UINT32_MAX || errno == ERANGE || *end)
9049 success = false;
9050 else
9051 upb_fielddef_setdefaultuint32(f, val);
9052 break;
9053 }
9054 case UPB_TYPE_UINT64: {
9055 /* XXX: Need to write our own strtoull, since it's not available in c89. */
9056 unsigned long long val = strtoul(str, &end, 0);
9057 if (val > UINT64_MAX || errno == ERANGE || *end)
9058 success = false;
9059 else
9060 upb_fielddef_setdefaultuint64(f, val);
9061 break;
9062 }
9063 case UPB_TYPE_DOUBLE: {
9064 double val = strtod(str, &end);
9065 if (errno == ERANGE || *end)
9066 success = false;
9067 else
9068 upb_fielddef_setdefaultdouble(f, val);
9069 break;
9070 }
9071 case UPB_TYPE_FLOAT: {
9072 /* XXX: Need to write our own strtof, since it's not available in c89. */
9073 float val = strtod(str, &end);
9074 if (errno == ERANGE || *end)
9075 success = false;
9076 else
9077 upb_fielddef_setdefaultfloat(f, val);
9078 break;
9079 }
9080 case UPB_TYPE_BOOL: {
9081 if (strcmp(str, "false") == 0)
9082 upb_fielddef_setdefaultbool(f, false);
9083 else if (strcmp(str, "true") == 0)
9084 upb_fielddef_setdefaultbool(f, true);
9085 else
9086 success = false;
9087 break;
9088 }
9089 default: abort();
9090 }
9091 return success;
9092}
9093
9094static bool field_endmsg(void *closure, const void *hd, upb_status *status) {
9095 upb_descreader *r = closure;
9096 upb_fielddef *f = r->f;
9097 UPB_UNUSED(hd);
9098
9099 /* TODO: verify that all required fields were present. */
Paul Yange0e54662016-09-15 11:09:01 -07009100 UPB_ASSERT(upb_fielddef_number(f) != 0);
9101 UPB_ASSERT(upb_fielddef_name(f) != NULL);
9102 UPB_ASSERT((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009103
9104 if (r->default_string) {
9105 if (upb_fielddef_issubmsg(f)) {
9106 upb_status_seterrmsg(status, "Submessages cannot have defaults.");
9107 return false;
9108 }
9109 if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) {
9110 upb_fielddef_setdefaultcstr(f, r->default_string, NULL);
9111 } else {
9112 if (r->default_string && !parse_default(r->default_string, f)) {
9113 /* We don't worry too much about giving a great error message since the
9114 * compiler should have ensured this was correct. */
9115 upb_status_seterrmsg(status, "Error converting default value.");
9116 return false;
9117 }
9118 }
9119 }
9120 return true;
9121}
9122
9123static bool field_onlazy(void *closure, const void *hd, bool val) {
9124 upb_descreader *r = closure;
9125 UPB_UNUSED(hd);
9126
9127 upb_fielddef_setlazy(r->f, val);
9128 return true;
9129}
9130
9131static bool field_onpacked(void *closure, const void *hd, bool val) {
9132 upb_descreader *r = closure;
9133 UPB_UNUSED(hd);
9134
9135 upb_fielddef_setpacked(r->f, val);
9136 return true;
9137}
9138
9139static bool field_ontype(void *closure, const void *hd, int32_t val) {
9140 upb_descreader *r = closure;
9141 UPB_UNUSED(hd);
9142
9143 upb_fielddef_setdescriptortype(r->f, val);
9144 return true;
9145}
9146
9147static bool field_onlabel(void *closure, const void *hd, int32_t val) {
9148 upb_descreader *r = closure;
9149 UPB_UNUSED(hd);
9150
9151 upb_fielddef_setlabel(r->f, val);
9152 return true;
9153}
9154
9155static bool field_onnumber(void *closure, const void *hd, int32_t val) {
9156 upb_descreader *r = closure;
Paul Yange0e54662016-09-15 11:09:01 -07009157 bool ok;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009158 UPB_UNUSED(hd);
9159
Paul Yange0e54662016-09-15 11:09:01 -07009160 ok = upb_fielddef_setnumber(r->f, val, NULL);
9161 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009162 return true;
9163}
9164
9165static size_t field_onname(void *closure, const void *hd, const char *buf,
9166 size_t n, const upb_bufhandle *handle) {
9167 upb_descreader *r = closure;
Paul Yang5a3405c2017-02-06 12:40:51 -08009168 char *name = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009169 UPB_UNUSED(hd);
9170 UPB_UNUSED(handle);
9171
9172 /* XXX: see comment at the top of the file. */
9173 upb_fielddef_setname(r->f, name, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009174 upb_gfree(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009175 return n;
9176}
9177
9178static size_t field_ontypename(void *closure, const void *hd, const char *buf,
9179 size_t n, const upb_bufhandle *handle) {
9180 upb_descreader *r = closure;
Paul Yang5a3405c2017-02-06 12:40:51 -08009181 char *name = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009182 UPB_UNUSED(hd);
9183 UPB_UNUSED(handle);
9184
9185 /* XXX: see comment at the top of the file. */
9186 upb_fielddef_setsubdefname(r->f, name, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009187 upb_gfree(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009188 return n;
9189}
9190
9191static size_t field_onextendee(void *closure, const void *hd, const char *buf,
9192 size_t n, const upb_bufhandle *handle) {
9193 upb_descreader *r = closure;
Paul Yang5a3405c2017-02-06 12:40:51 -08009194 char *name = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009195 UPB_UNUSED(hd);
9196 UPB_UNUSED(handle);
9197
9198 /* XXX: see comment at the top of the file. */
9199 upb_fielddef_setcontainingtypename(r->f, name, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009200 upb_gfree(name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009201 return n;
9202}
9203
9204static size_t field_ondefaultval(void *closure, const void *hd, const char *buf,
9205 size_t n, const upb_bufhandle *handle) {
9206 upb_descreader *r = closure;
9207 UPB_UNUSED(hd);
9208 UPB_UNUSED(handle);
9209
9210 /* Have to convert from string to the correct type, but we might not know the
9211 * type yet, so we save it as a string until the end of the field.
9212 * XXX: see comment at the top of the file. */
Paul Yange0e54662016-09-15 11:09:01 -07009213 upb_gfree(r->default_string);
Paul Yang5a3405c2017-02-06 12:40:51 -08009214 r->default_string = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009215 return n;
9216}
9217
Paul Yange0e54662016-09-15 11:09:01 -07009218static bool field_ononeofindex(void *closure, const void *hd, int32_t index) {
9219 upb_descreader *r = closure;
9220 upb_oneofdef *o = upb_descreader_getoneof(r, index);
9221 bool ok = upb_oneofdef_addfield(o, r->f, &r->f, NULL);
9222 UPB_UNUSED(hd);
9223
9224 UPB_ASSERT(ok);
9225 return true;
9226}
9227
9228/** Handlers for google.protobuf.OneofDescriptorProto. ************************/
9229
9230static size_t oneof_name(void *closure, const void *hd, const char *buf,
9231 size_t n, const upb_bufhandle *handle) {
9232 upb_descreader *r = closure;
9233 upb_descreader_frame *f = &r->stack[r->stack_len-1];
9234 upb_oneofdef *o = upb_descreader_getoneof(r, f->oneof_index++);
Paul Yang5a3405c2017-02-06 12:40:51 -08009235 char *name_null_terminated = upb_gstrndup(buf, n);
Paul Yange0e54662016-09-15 11:09:01 -07009236 bool ok = upb_oneofdef_setname(o, name_null_terminated, NULL);
9237 UPB_UNUSED(hd);
9238 UPB_UNUSED(handle);
9239
9240 UPB_ASSERT(ok);
9241 free(name_null_terminated);
9242 return n;
9243}
9244
9245/** Handlers for google.protobuf.DescriptorProto ******************************/
9246
9247static bool msg_start(void *closure, const void *hd) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009248 upb_descreader *r = closure;
9249 UPB_UNUSED(hd);
9250
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009251 upb_descreader_startcontainer(r);
9252 return true;
9253}
9254
Paul Yange0e54662016-09-15 11:09:01 -07009255static bool msg_end(void *closure, const void *hd, upb_status *status) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009256 upb_descreader *r = closure;
9257 upb_msgdef *m = upb_descreader_top(r);
9258 UPB_UNUSED(hd);
9259
9260 if(!upb_def_fullname(upb_msgdef_upcast_mutable(m))) {
9261 upb_status_seterrmsg(status, "Encountered message with no name.");
9262 return false;
9263 }
Paul Yange0e54662016-09-15 11:09:01 -07009264 return upb_descreader_endcontainer(r);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009265}
9266
Paul Yange0e54662016-09-15 11:09:01 -07009267static size_t msg_name(void *closure, const void *hd, const char *buf,
9268 size_t n, const upb_bufhandle *handle) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009269 upb_descreader *r = closure;
9270 upb_msgdef *m = upb_descreader_top(r);
9271 /* XXX: see comment at the top of the file. */
Paul Yang5a3405c2017-02-06 12:40:51 -08009272 char *name = upb_gstrndup(buf, n);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009273 UPB_UNUSED(hd);
9274 UPB_UNUSED(handle);
9275
9276 upb_def_setfullname(upb_msgdef_upcast_mutable(m), name, NULL);
9277 upb_descreader_setscopename(r, name); /* Passes ownership of name. */
Paul Yang9bda1f12018-09-22 18:57:43 -07009278
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009279 return n;
9280}
9281
Paul Yange0e54662016-09-15 11:09:01 -07009282static void *msg_startmsg(void *closure, const void *hd) {
9283 upb_descreader *r = closure;
9284 upb_msgdef *m = upb_msgdef_new(&m);
9285 bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
9286 UPB_UNUSED(hd);
9287 UPB_ASSERT(ok);
9288 return r;
9289}
9290
9291static void *msg_startext(void *closure, const void *hd) {
9292 upb_descreader *r = closure;
Paul Yang57b65972019-03-19 22:27:13 -07009293 r->f = upb_fielddef_new(r);
Paul Yange0e54662016-09-15 11:09:01 -07009294 UPB_UNUSED(hd);
Paul Yange0e54662016-09-15 11:09:01 -07009295 return r;
9296}
9297
Paul Yang57b65972019-03-19 22:27:13 -07009298static bool msg_endext(void *closure, const void *hd) {
9299 /* The current symtab code can't handle extensions, so we just discard
9300 * them for now. */
9301 upb_descreader *r = closure;
9302 upb_fielddef_unref(r->f, r);
9303 UPB_UNUSED(hd);
9304 r->f = NULL;
9305 return true;
9306}
9307
Paul Yange0e54662016-09-15 11:09:01 -07009308static void *msg_startfield(void *closure, const void *hd) {
9309 upb_descreader *r = closure;
9310 r->f = upb_fielddef_new(&r->f);
9311 /* We can't add the new field to the message until its name/number are
9312 * filled in. */
9313 UPB_UNUSED(hd);
9314 return r;
9315}
9316
9317static bool msg_endfield(void *closure, const void *hd) {
9318 upb_descreader *r = closure;
9319 upb_msgdef *m = upb_descreader_top(r);
9320 bool ok;
9321 UPB_UNUSED(hd);
9322
9323 /* Oneof fields are added to the msgdef through their oneof, so don't need to
9324 * be added here. */
9325 if (upb_fielddef_containingoneof(r->f) == NULL) {
9326 ok = upb_msgdef_addfield(m, r->f, &r->f, NULL);
9327 UPB_ASSERT(ok);
9328 }
9329 r->f = NULL;
9330 return true;
9331}
9332
9333static bool msg_onmapentry(void *closure, const void *hd, bool mapentry) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009334 upb_descreader *r = closure;
9335 upb_msgdef *m = upb_descreader_top(r);
9336 UPB_UNUSED(hd);
9337
Paul Yange0e54662016-09-15 11:09:01 -07009338 upb_msgdef_setmapentry(m, mapentry);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009339 r->f = NULL;
9340 return true;
9341}
9342
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009343
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009344
Paul Yange0e54662016-09-15 11:09:01 -07009345/** Code to register handlers *************************************************/
9346
9347#define F(msg, field) upbdefs_google_protobuf_ ## msg ## _f_ ## field(m)
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009348
9349static void reghandlers(const void *closure, upb_handlers *h) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009350 const upb_msgdef *m = upb_handlers_msgdef(h);
Paul Yange0e54662016-09-15 11:09:01 -07009351 UPB_UNUSED(closure);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009352
Paul Yange0e54662016-09-15 11:09:01 -07009353 if (upbdefs_google_protobuf_FileDescriptorSet_is(m)) {
9354 upb_handlers_setstartsubmsg(h, F(FileDescriptorSet, file),
9355 &fileset_startfile, NULL);
9356 } else if (upbdefs_google_protobuf_DescriptorProto_is(m)) {
9357 upb_handlers_setstartmsg(h, &msg_start, NULL);
9358 upb_handlers_setendmsg(h, &msg_end, NULL);
9359 upb_handlers_setstring(h, F(DescriptorProto, name), &msg_name, NULL);
9360 upb_handlers_setstartsubmsg(h, F(DescriptorProto, extension), &msg_startext,
9361 NULL);
Paul Yang57b65972019-03-19 22:27:13 -07009362 upb_handlers_setendsubmsg(h, F(DescriptorProto, extension), &msg_endext,
9363 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009364 upb_handlers_setstartsubmsg(h, F(DescriptorProto, nested_type),
9365 &msg_startmsg, NULL);
9366 upb_handlers_setstartsubmsg(h, F(DescriptorProto, field),
9367 &msg_startfield, NULL);
9368 upb_handlers_setendsubmsg(h, F(DescriptorProto, field),
9369 &msg_endfield, NULL);
9370 upb_handlers_setstartsubmsg(h, F(DescriptorProto, enum_type),
9371 &file_startenum, NULL);
9372 } else if (upbdefs_google_protobuf_FileDescriptorProto_is(m)) {
9373 upb_handlers_setstartmsg(h, &file_start, NULL);
9374 upb_handlers_setendmsg(h, &file_end, NULL);
9375 upb_handlers_setstring(h, F(FileDescriptorProto, name), &file_onname,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009376 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009377 upb_handlers_setstring(h, F(FileDescriptorProto, package), &file_onpackage,
9378 NULL);
9379 upb_handlers_setstring(h, F(FileDescriptorProto, syntax), &file_onsyntax,
9380 NULL);
9381 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, message_type),
9382 &file_startmsg, NULL);
9383 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, enum_type),
9384 &file_startenum, NULL);
9385 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension),
9386 &file_startext, NULL);
Paul Yang57b65972019-03-19 22:27:13 -07009387 upb_handlers_setendsubmsg(h, F(FileDescriptorProto, extension),
9388 &file_endext, NULL);
Paul Yang60327462017-10-09 12:39:13 -07009389 upb_handlers_setstring(h, F(FileDescriptorProto, dependency),
9390 &file_ondep, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009391 } else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009392 upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
9393 upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009394 upb_handlers_setstring(h, F(EnumValueDescriptorProto, name), &enumval_onname, NULL);
9395 upb_handlers_setint32(h, F(EnumValueDescriptorProto, number), &enumval_onnumber,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009396 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009397 } else if (upbdefs_google_protobuf_EnumDescriptorProto_is(m)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009398 upb_handlers_setendmsg(h, &enum_endmsg, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009399 upb_handlers_setstring(h, F(EnumDescriptorProto, name), &enum_onname, NULL);
9400 } else if (upbdefs_google_protobuf_FieldDescriptorProto_is(m)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009401 upb_handlers_setstartmsg(h, &field_startmsg, NULL);
9402 upb_handlers_setendmsg(h, &field_endmsg, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009403 upb_handlers_setint32(h, F(FieldDescriptorProto, type), &field_ontype,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009404 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009405 upb_handlers_setint32(h, F(FieldDescriptorProto, label), &field_onlabel,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009406 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009407 upb_handlers_setint32(h, F(FieldDescriptorProto, number), &field_onnumber,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009408 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009409 upb_handlers_setstring(h, F(FieldDescriptorProto, name), &field_onname,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009410 NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009411 upb_handlers_setstring(h, F(FieldDescriptorProto, type_name),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009412 &field_ontypename, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009413 upb_handlers_setstring(h, F(FieldDescriptorProto, extendee),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009414 &field_onextendee, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009415 upb_handlers_setstring(h, F(FieldDescriptorProto, default_value),
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009416 &field_ondefaultval, NULL);
Paul Yange0e54662016-09-15 11:09:01 -07009417 upb_handlers_setint32(h, F(FieldDescriptorProto, oneof_index),
9418 &field_ononeofindex, NULL);
9419 } else if (upbdefs_google_protobuf_OneofDescriptorProto_is(m)) {
9420 upb_handlers_setstring(h, F(OneofDescriptorProto, name), &oneof_name, NULL);
9421 } else if (upbdefs_google_protobuf_FieldOptions_is(m)) {
9422 upb_handlers_setbool(h, F(FieldOptions, lazy), &field_onlazy, NULL);
9423 upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL);
9424 } else if (upbdefs_google_protobuf_MessageOptions_is(m)) {
9425 upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL);
Paul Yang6b27c1f2017-03-17 11:08:06 -07009426 } else if (upbdefs_google_protobuf_FileOptions_is(m)) {
9427 upb_handlers_setstring(h, F(FileOptions, php_class_prefix),
9428 &file_onphpprefix, NULL);
Paul Yang6f325802017-06-05 00:10:18 -07009429 upb_handlers_setstartstr(h, F(FileOptions, php_namespace),
9430 &file_startphpnamespace, NULL);
9431 upb_handlers_setstring(h, F(FileOptions, php_namespace),
9432 &file_onphpnamespace, NULL);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009433 }
Paul Yange0e54662016-09-15 11:09:01 -07009434
9435 UPB_ASSERT(upb_ok(upb_handlers_status(h)));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009436}
9437
Paul Yange0e54662016-09-15 11:09:01 -07009438#undef F
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009439
9440void descreader_cleanup(void *_r) {
9441 upb_descreader *r = _r;
Paul Yange0e54662016-09-15 11:09:01 -07009442 size_t i;
9443
9444 for (i = 0; i < upb_descreader_filecount(r); i++) {
9445 upb_filedef_unref(upb_descreader_file(r, i), &r->files);
9446 }
9447
9448 upb_gfree(r->name);
9449 upb_inttable_uninit(&r->files);
Paul Yang60327462017-10-09 12:39:13 -07009450 upb_strtable_uninit(&r->files_by_name);
Paul Yange0e54662016-09-15 11:09:01 -07009451 upb_inttable_uninit(&r->oneofs);
9452 upb_gfree(r->default_string);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009453 while (r->stack_len > 0) {
9454 upb_descreader_frame *f = &r->stack[--r->stack_len];
Paul Yange0e54662016-09-15 11:09:01 -07009455 upb_gfree(f->name);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009456 }
9457}
9458
9459
9460/* Public API ****************************************************************/
9461
9462upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
9463 upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader));
9464 if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) {
9465 return NULL;
9466 }
9467
Paul Yange0e54662016-09-15 11:09:01 -07009468 upb_inttable_init(&r->files, UPB_CTYPE_PTR);
Paul Yang60327462017-10-09 12:39:13 -07009469 upb_strtable_init(&r->files_by_name, UPB_CTYPE_PTR);
Paul Yange0e54662016-09-15 11:09:01 -07009470 upb_inttable_init(&r->oneofs, UPB_CTYPE_PTR);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009471 upb_sink_reset(upb_descreader_input(r), h, r);
9472 r->stack_len = 0;
9473 r->name = NULL;
9474 r->default_string = NULL;
9475
9476 return r;
9477}
9478
Paul Yange0e54662016-09-15 11:09:01 -07009479size_t upb_descreader_filecount(const upb_descreader *r) {
9480 return upb_inttable_count(&r->files);
9481}
9482
9483upb_filedef *upb_descreader_file(const upb_descreader *r, size_t i) {
9484 upb_value v;
9485 if (upb_inttable_lookup(&r->files, i, &v)) {
9486 return upb_value_getptr(v);
9487 } else {
9488 return NULL;
9489 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009490}
9491
9492upb_sink *upb_descreader_input(upb_descreader *r) {
9493 return &r->sink;
9494}
9495
9496const upb_handlers *upb_descreader_newhandlers(const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -07009497 const upb_msgdef *m = upbdefs_google_protobuf_FileDescriptorSet_get(&m);
9498 const upb_handlers *h = upb_handlers_newfrozen(m, owner, reghandlers, NULL);
9499 upb_msgdef_unref(m, &m);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009500 return h;
9501}
9502/*
9503** protobuf decoder bytecode compiler
9504**
9505** Code to compile a upb::Handlers into bytecode for decoding a protobuf
9506** according to that specific schema and destination handlers.
9507**
9508** Compiling to bytecode is always the first step. If we are using the
9509** interpreted decoder we leave it as bytecode and interpret that. If we are
9510** using a JIT decoder we use a code generator to turn the bytecode into native
9511** code, LLVM IR, etc.
9512**
9513** Bytecode definition is in decoder.int.h.
9514*/
9515
9516#include <stdarg.h>
9517
9518#ifdef UPB_DUMP_BYTECODE
9519#include <stdio.h>
9520#endif
9521
9522#define MAXLABEL 5
9523#define EMPTYLABEL -1
9524
9525/* mgroup *********************************************************************/
9526
9527static void freegroup(upb_refcounted *r) {
9528 mgroup *g = (mgroup*)r;
9529 upb_inttable_uninit(&g->methods);
9530#ifdef UPB_USE_JIT_X64
9531 upb_pbdecoder_freejit(g);
9532#endif
Paul Yange0e54662016-09-15 11:09:01 -07009533 upb_gfree(g->bytecode);
9534 upb_gfree(g);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009535}
9536
9537static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
9538 void *closure) {
9539 const mgroup *g = (const mgroup*)r;
9540 upb_inttable_iter i;
9541 upb_inttable_begin(&i, &g->methods);
9542 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
9543 upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
9544 visit(r, upb_pbdecodermethod_upcast(method), closure);
9545 }
9546}
9547
9548mgroup *newgroup(const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -07009549 mgroup *g = upb_gmalloc(sizeof(*g));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009550 static const struct upb_refcounted_vtbl vtbl = {visitgroup, freegroup};
9551 upb_refcounted_init(mgroup_upcast_mutable(g), &vtbl, owner);
9552 upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
9553 g->bytecode = NULL;
9554 g->bytecode_end = NULL;
9555 return g;
9556}
9557
9558
9559/* upb_pbdecodermethod ********************************************************/
9560
9561static void freemethod(upb_refcounted *r) {
9562 upb_pbdecodermethod *method = (upb_pbdecodermethod*)r;
9563
9564 if (method->dest_handlers_) {
9565 upb_handlers_unref(method->dest_handlers_, method);
9566 }
9567
9568 upb_inttable_uninit(&method->dispatch);
Paul Yange0e54662016-09-15 11:09:01 -07009569 upb_gfree(method);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009570}
9571
9572static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
9573 void *closure) {
9574 const upb_pbdecodermethod *m = (const upb_pbdecodermethod*)r;
9575 visit(r, m->group, closure);
9576}
9577
9578static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
9579 mgroup *group) {
9580 static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod};
Paul Yange0e54662016-09-15 11:09:01 -07009581 upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009582 upb_refcounted_init(upb_pbdecodermethod_upcast_mutable(ret), &vtbl, &ret);
9583 upb_byteshandler_init(&ret->input_handler_);
9584
9585 /* The method references the group and vice-versa, in a circular reference. */
9586 upb_ref2(ret, group);
9587 upb_ref2(group, ret);
9588 upb_inttable_insertptr(&group->methods, dest_handlers, upb_value_ptr(ret));
9589 upb_pbdecodermethod_unref(ret, &ret);
9590
9591 ret->group = mgroup_upcast_mutable(group);
9592 ret->dest_handlers_ = dest_handlers;
9593 ret->is_native_ = false; /* If we JIT, it will update this later. */
9594 upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64);
9595
9596 if (ret->dest_handlers_) {
9597 upb_handlers_ref(ret->dest_handlers_, ret);
9598 }
9599 return ret;
9600}
9601
9602const upb_handlers *upb_pbdecodermethod_desthandlers(
9603 const upb_pbdecodermethod *m) {
9604 return m->dest_handlers_;
9605}
9606
9607const upb_byteshandler *upb_pbdecodermethod_inputhandler(
9608 const upb_pbdecodermethod *m) {
9609 return &m->input_handler_;
9610}
9611
9612bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m) {
9613 return m->is_native_;
9614}
9615
9616const upb_pbdecodermethod *upb_pbdecodermethod_new(
9617 const upb_pbdecodermethodopts *opts, const void *owner) {
9618 const upb_pbdecodermethod *ret;
9619 upb_pbcodecache cache;
9620
9621 upb_pbcodecache_init(&cache);
9622 ret = upb_pbcodecache_getdecodermethod(&cache, opts);
9623 upb_pbdecodermethod_ref(ret, owner);
9624 upb_pbcodecache_uninit(&cache);
9625 return ret;
9626}
9627
9628
9629/* bytecode compiler **********************************************************/
9630
9631/* Data used only at compilation time. */
9632typedef struct {
9633 mgroup *group;
9634
9635 uint32_t *pc;
9636 int fwd_labels[MAXLABEL];
9637 int back_labels[MAXLABEL];
9638
9639 /* For fields marked "lazy", parse them lazily or eagerly? */
9640 bool lazy;
9641} compiler;
9642
9643static compiler *newcompiler(mgroup *group, bool lazy) {
Paul Yange0e54662016-09-15 11:09:01 -07009644 compiler *ret = upb_gmalloc(sizeof(*ret));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009645 int i;
9646
9647 ret->group = group;
9648 ret->lazy = lazy;
9649 for (i = 0; i < MAXLABEL; i++) {
9650 ret->fwd_labels[i] = EMPTYLABEL;
9651 ret->back_labels[i] = EMPTYLABEL;
9652 }
9653 return ret;
9654}
9655
9656static void freecompiler(compiler *c) {
Paul Yange0e54662016-09-15 11:09:01 -07009657 upb_gfree(c);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009658}
9659
9660const size_t ptr_words = sizeof(void*) / sizeof(uint32_t);
9661
9662/* How many words an instruction is. */
9663static int instruction_len(uint32_t instr) {
9664 switch (getop(instr)) {
9665 case OP_SETDISPATCH: return 1 + ptr_words;
9666 case OP_TAGN: return 3;
9667 case OP_SETBIGGROUPNUM: return 2;
9668 default: return 1;
9669 }
9670}
9671
9672bool op_has_longofs(int32_t instruction) {
9673 switch (getop(instruction)) {
9674 case OP_CALL:
9675 case OP_BRANCH:
9676 case OP_CHECKDELIM:
9677 return true;
9678 /* The "tag" instructions only have 8 bytes available for the jump target,
9679 * but that is ok because these opcodes only require short jumps. */
9680 case OP_TAG1:
9681 case OP_TAG2:
9682 case OP_TAGN:
9683 return false;
9684 default:
Paul Yange0e54662016-09-15 11:09:01 -07009685 UPB_ASSERT(false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009686 return false;
9687 }
9688}
9689
9690static int32_t getofs(uint32_t instruction) {
9691 if (op_has_longofs(instruction)) {
9692 return (int32_t)instruction >> 8;
9693 } else {
9694 return (int8_t)(instruction >> 8);
9695 }
9696}
9697
9698static void setofs(uint32_t *instruction, int32_t ofs) {
9699 if (op_has_longofs(*instruction)) {
9700 *instruction = getop(*instruction) | ofs << 8;
9701 } else {
9702 *instruction = (*instruction & ~0xff00) | ((ofs & 0xff) << 8);
9703 }
Paul Yange0e54662016-09-15 11:09:01 -07009704 UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009705}
9706
9707static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; }
9708
9709/* Defines a local label at the current PC location. All previous forward
9710 * references are updated to point to this location. The location is noted
9711 * for any future backward references. */
9712static void label(compiler *c, unsigned int label) {
9713 int val;
9714 uint32_t *codep;
9715
Paul Yange0e54662016-09-15 11:09:01 -07009716 UPB_ASSERT(label < MAXLABEL);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009717 val = c->fwd_labels[label];
9718 codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val;
9719 while (codep) {
9720 int ofs = getofs(*codep);
9721 setofs(codep, c->pc - codep - instruction_len(*codep));
9722 codep = ofs ? codep + ofs : NULL;
9723 }
9724 c->fwd_labels[label] = EMPTYLABEL;
9725 c->back_labels[label] = pcofs(c);
9726}
9727
9728/* Creates a reference to a numbered label; either a forward reference
9729 * (positive arg) or backward reference (negative arg). For forward references
9730 * the value returned now is actually a "next" pointer into a linked list of all
9731 * instructions that use this label and will be patched later when the label is
9732 * defined with label().
9733 *
9734 * The returned value is the offset that should be written into the instruction.
9735 */
9736static int32_t labelref(compiler *c, int label) {
Paul Yange0e54662016-09-15 11:09:01 -07009737 UPB_ASSERT(label < MAXLABEL);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009738 if (label == LABEL_DISPATCH) {
9739 /* No resolving required. */
9740 return 0;
9741 } else if (label < 0) {
9742 /* Backward local label. Relative to the next instruction. */
9743 uint32_t from = (c->pc + 1) - c->group->bytecode;
9744 return c->back_labels[-label] - from;
9745 } else {
9746 /* Forward local label: prepend to (possibly-empty) linked list. */
9747 int *lptr = &c->fwd_labels[label];
9748 int32_t ret = (*lptr == EMPTYLABEL) ? 0 : *lptr - pcofs(c);
9749 *lptr = pcofs(c);
9750 return ret;
9751 }
9752}
9753
9754static void put32(compiler *c, uint32_t v) {
9755 mgroup *g = c->group;
9756 if (c->pc == g->bytecode_end) {
9757 int ofs = pcofs(c);
9758 size_t oldsize = g->bytecode_end - g->bytecode;
9759 size_t newsize = UPB_MAX(oldsize * 2, 64);
9760 /* TODO(haberman): handle OOM. */
Paul Yange0e54662016-09-15 11:09:01 -07009761 g->bytecode = upb_grealloc(g->bytecode, oldsize * sizeof(uint32_t),
9762 newsize * sizeof(uint32_t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009763 g->bytecode_end = g->bytecode + newsize;
9764 c->pc = g->bytecode + ofs;
9765 }
9766 *c->pc++ = v;
9767}
9768
Paul Yang60327462017-10-09 12:39:13 -07009769static void putop(compiler *c, int op, ...) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009770 va_list ap;
9771 va_start(ap, op);
9772
9773 switch (op) {
9774 case OP_SETDISPATCH: {
9775 uintptr_t ptr = (uintptr_t)va_arg(ap, void*);
9776 put32(c, OP_SETDISPATCH);
9777 put32(c, ptr);
9778 if (sizeof(uintptr_t) > sizeof(uint32_t))
9779 put32(c, (uint64_t)ptr >> 32);
9780 break;
9781 }
9782 case OP_STARTMSG:
9783 case OP_ENDMSG:
9784 case OP_PUSHLENDELIM:
9785 case OP_POP:
9786 case OP_SETDELIM:
9787 case OP_HALT:
9788 case OP_RET:
9789 case OP_DISPATCH:
9790 put32(c, op);
9791 break;
9792 case OP_PARSE_DOUBLE:
9793 case OP_PARSE_FLOAT:
9794 case OP_PARSE_INT64:
9795 case OP_PARSE_UINT64:
9796 case OP_PARSE_INT32:
9797 case OP_PARSE_FIXED64:
9798 case OP_PARSE_FIXED32:
9799 case OP_PARSE_BOOL:
9800 case OP_PARSE_UINT32:
9801 case OP_PARSE_SFIXED32:
9802 case OP_PARSE_SFIXED64:
9803 case OP_PARSE_SINT32:
9804 case OP_PARSE_SINT64:
9805 case OP_STARTSEQ:
9806 case OP_ENDSEQ:
9807 case OP_STARTSUBMSG:
9808 case OP_ENDSUBMSG:
9809 case OP_STARTSTR:
9810 case OP_STRING:
9811 case OP_ENDSTR:
9812 case OP_PUSHTAGDELIM:
9813 put32(c, op | va_arg(ap, upb_selector_t) << 8);
9814 break;
9815 case OP_SETBIGGROUPNUM:
9816 put32(c, op);
9817 put32(c, va_arg(ap, int));
9818 break;
9819 case OP_CALL: {
9820 const upb_pbdecodermethod *method = va_arg(ap, upb_pbdecodermethod *);
9821 put32(c, op | (method->code_base.ofs - (pcofs(c) + 1)) << 8);
9822 break;
9823 }
9824 case OP_CHECKDELIM:
9825 case OP_BRANCH: {
9826 uint32_t instruction = op;
9827 int label = va_arg(ap, int);
9828 setofs(&instruction, labelref(c, label));
9829 put32(c, instruction);
9830 break;
9831 }
9832 case OP_TAG1:
9833 case OP_TAG2: {
9834 int label = va_arg(ap, int);
9835 uint64_t tag = va_arg(ap, uint64_t);
9836 uint32_t instruction = op | (tag << 16);
Paul Yange0e54662016-09-15 11:09:01 -07009837 UPB_ASSERT(tag <= 0xffff);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009838 setofs(&instruction, labelref(c, label));
9839 put32(c, instruction);
9840 break;
9841 }
9842 case OP_TAGN: {
9843 int label = va_arg(ap, int);
9844 uint64_t tag = va_arg(ap, uint64_t);
9845 uint32_t instruction = op | (upb_value_size(tag) << 16);
9846 setofs(&instruction, labelref(c, label));
9847 put32(c, instruction);
9848 put32(c, tag);
9849 put32(c, tag >> 32);
9850 break;
9851 }
9852 }
9853
9854 va_end(ap);
9855}
9856
9857#if defined(UPB_USE_JIT_X64) || defined(UPB_DUMP_BYTECODE)
9858
9859const char *upb_pbdecoder_getopname(unsigned int op) {
9860#define QUOTE(x) #x
9861#define EXPAND_AND_QUOTE(x) QUOTE(x)
9862#define OPNAME(x) OP_##x
9863#define OP(x) case OPNAME(x): return EXPAND_AND_QUOTE(OPNAME(x));
9864#define T(x) OP(PARSE_##x)
9865 /* Keep in sync with list in decoder.int.h. */
9866 switch ((opcode)op) {
9867 T(DOUBLE) T(FLOAT) T(INT64) T(UINT64) T(INT32) T(FIXED64) T(FIXED32)
9868 T(BOOL) T(UINT32) T(SFIXED32) T(SFIXED64) T(SINT32) T(SINT64)
9869 OP(STARTMSG) OP(ENDMSG) OP(STARTSEQ) OP(ENDSEQ) OP(STARTSUBMSG)
9870 OP(ENDSUBMSG) OP(STARTSTR) OP(STRING) OP(ENDSTR) OP(CALL) OP(RET)
9871 OP(PUSHLENDELIM) OP(PUSHTAGDELIM) OP(SETDELIM) OP(CHECKDELIM)
9872 OP(BRANCH) OP(TAG1) OP(TAG2) OP(TAGN) OP(SETDISPATCH) OP(POP)
9873 OP(SETBIGGROUPNUM) OP(DISPATCH) OP(HALT)
9874 }
9875 return "<unknown op>";
9876#undef OP
9877#undef T
9878}
9879
9880#endif
9881
9882#ifdef UPB_DUMP_BYTECODE
9883
9884static void dumpbc(uint32_t *p, uint32_t *end, FILE *f) {
9885
9886 uint32_t *begin = p;
9887
9888 while (p < end) {
9889 fprintf(f, "%p %8tx", p, p - begin);
9890 uint32_t instr = *p++;
9891 uint8_t op = getop(instr);
9892 fprintf(f, " %s", upb_pbdecoder_getopname(op));
9893 switch ((opcode)op) {
9894 case OP_SETDISPATCH: {
9895 const upb_inttable *dispatch;
9896 memcpy(&dispatch, p, sizeof(void*));
9897 p += ptr_words;
9898 const upb_pbdecodermethod *method =
9899 (void *)((char *)dispatch -
9900 offsetof(upb_pbdecodermethod, dispatch));
9901 fprintf(f, " %s", upb_msgdef_fullname(
9902 upb_handlers_msgdef(method->dest_handlers_)));
9903 break;
9904 }
9905 case OP_DISPATCH:
9906 case OP_STARTMSG:
9907 case OP_ENDMSG:
9908 case OP_PUSHLENDELIM:
9909 case OP_POP:
9910 case OP_SETDELIM:
9911 case OP_HALT:
9912 case OP_RET:
9913 break;
9914 case OP_PARSE_DOUBLE:
9915 case OP_PARSE_FLOAT:
9916 case OP_PARSE_INT64:
9917 case OP_PARSE_UINT64:
9918 case OP_PARSE_INT32:
9919 case OP_PARSE_FIXED64:
9920 case OP_PARSE_FIXED32:
9921 case OP_PARSE_BOOL:
9922 case OP_PARSE_UINT32:
9923 case OP_PARSE_SFIXED32:
9924 case OP_PARSE_SFIXED64:
9925 case OP_PARSE_SINT32:
9926 case OP_PARSE_SINT64:
9927 case OP_STARTSEQ:
9928 case OP_ENDSEQ:
9929 case OP_STARTSUBMSG:
9930 case OP_ENDSUBMSG:
9931 case OP_STARTSTR:
9932 case OP_STRING:
9933 case OP_ENDSTR:
9934 case OP_PUSHTAGDELIM:
9935 fprintf(f, " %d", instr >> 8);
9936 break;
9937 case OP_SETBIGGROUPNUM:
9938 fprintf(f, " %d", *p++);
9939 break;
9940 case OP_CHECKDELIM:
9941 case OP_CALL:
9942 case OP_BRANCH:
9943 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
9944 break;
9945 case OP_TAG1:
9946 case OP_TAG2: {
9947 fprintf(f, " tag:0x%x", instr >> 16);
9948 if (getofs(instr)) {
9949 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
9950 }
9951 break;
9952 }
9953 case OP_TAGN: {
9954 uint64_t tag = *p++;
9955 tag |= (uint64_t)*p++ << 32;
9956 fprintf(f, " tag:0x%llx", (long long)tag);
9957 fprintf(f, " n:%d", instr >> 16);
9958 if (getofs(instr)) {
9959 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
9960 }
9961 break;
9962 }
9963 }
9964 fputs("\n", f);
9965 }
9966}
9967
9968#endif
9969
9970static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type) {
9971 uint32_t tag = (upb_fielddef_number(f) << 3) | wire_type;
9972 uint64_t encoded_tag = upb_vencode32(tag);
9973 /* No tag should be greater than 5 bytes. */
Paul Yange0e54662016-09-15 11:09:01 -07009974 UPB_ASSERT(encoded_tag <= 0xffffffffff);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009975 return encoded_tag;
9976}
9977
9978static void putchecktag(compiler *c, const upb_fielddef *f,
9979 int wire_type, int dest) {
9980 uint64_t tag = get_encoded_tag(f, wire_type);
9981 switch (upb_value_size(tag)) {
9982 case 1:
9983 putop(c, OP_TAG1, dest, tag);
9984 break;
9985 case 2:
9986 putop(c, OP_TAG2, dest, tag);
9987 break;
9988 default:
9989 putop(c, OP_TAGN, dest, tag);
9990 break;
9991 }
9992}
9993
9994static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
9995 upb_selector_t selector;
9996 bool ok = upb_handlers_getselector(f, type, &selector);
Paul Yange0e54662016-09-15 11:09:01 -07009997 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -07009998 return selector;
9999}
10000
10001/* Takes an existing, primary dispatch table entry and repacks it with a
10002 * different alternate wire type. Called when we are inserting a secondary
10003 * dispatch table entry for an alternate wire type. */
10004static uint64_t repack(uint64_t dispatch, int new_wt2) {
10005 uint64_t ofs;
10006 uint8_t wt1;
10007 uint8_t old_wt2;
10008 upb_pbdecoder_unpackdispatch(dispatch, &ofs, &wt1, &old_wt2);
Paul Yange0e54662016-09-15 11:09:01 -070010009 UPB_ASSERT(old_wt2 == NO_WIRE_TYPE); /* wt2 should not be set yet. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010010 return upb_pbdecoder_packdispatch(ofs, wt1, new_wt2);
10011}
10012
10013/* Marks the current bytecode position as the dispatch target for this message,
10014 * field, and wire type. */
10015static void dispatchtarget(compiler *c, upb_pbdecodermethod *method,
10016 const upb_fielddef *f, int wire_type) {
10017 /* Offset is relative to msg base. */
10018 uint64_t ofs = pcofs(c) - method->code_base.ofs;
10019 uint32_t fn = upb_fielddef_number(f);
10020 upb_inttable *d = &method->dispatch;
10021 upb_value v;
10022 if (upb_inttable_remove(d, fn, &v)) {
10023 /* TODO: prioritize based on packed setting in .proto file. */
10024 uint64_t repacked = repack(upb_value_getuint64(v), wire_type);
10025 upb_inttable_insert(d, fn, upb_value_uint64(repacked));
10026 upb_inttable_insert(d, fn + UPB_MAX_FIELDNUMBER, upb_value_uint64(ofs));
10027 } else {
10028 uint64_t val = upb_pbdecoder_packdispatch(ofs, wire_type, NO_WIRE_TYPE);
10029 upb_inttable_insert(d, fn, upb_value_uint64(val));
10030 }
10031}
10032
10033static void putpush(compiler *c, const upb_fielddef *f) {
10034 if (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE) {
10035 putop(c, OP_PUSHLENDELIM);
10036 } else {
10037 uint32_t fn = upb_fielddef_number(f);
10038 if (fn >= 1 << 24) {
10039 putop(c, OP_PUSHTAGDELIM, 0);
10040 putop(c, OP_SETBIGGROUPNUM, fn);
10041 } else {
10042 putop(c, OP_PUSHTAGDELIM, fn);
10043 }
10044 }
10045}
10046
10047static upb_pbdecodermethod *find_submethod(const compiler *c,
10048 const upb_pbdecodermethod *method,
10049 const upb_fielddef *f) {
10050 const upb_handlers *sub =
10051 upb_handlers_getsubhandlers(method->dest_handlers_, f);
10052 upb_value v;
10053 return upb_inttable_lookupptr(&c->group->methods, sub, &v)
10054 ? upb_value_getptr(v)
10055 : NULL;
10056}
10057
10058static void putsel(compiler *c, opcode op, upb_selector_t sel,
10059 const upb_handlers *h) {
10060 if (upb_handlers_gethandler(h, sel)) {
10061 putop(c, op, sel);
10062 }
10063}
10064
10065/* Puts an opcode to call a callback, but only if a callback actually exists for
10066 * this field and handler type. */
10067static void maybeput(compiler *c, opcode op, const upb_handlers *h,
10068 const upb_fielddef *f, upb_handlertype_t type) {
10069 putsel(c, op, getsel(f, type), h);
10070}
10071
10072static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) {
10073 if (!upb_fielddef_lazy(f))
10074 return false;
10075
10076 return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR)) ||
10077 upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING)) ||
10078 upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR));
10079}
10080
10081
10082/* bytecode compiler code generation ******************************************/
10083
10084/* Symbolic names for our local labels. */
10085#define LABEL_LOOPSTART 1 /* Top of a repeated field loop. */
10086#define LABEL_LOOPBREAK 2 /* To jump out of a repeated loop */
10087#define LABEL_FIELD 3 /* Jump backward to find the most recent field. */
10088#define LABEL_ENDMSG 4 /* To reach the OP_ENDMSG instr for this msg. */
10089
10090/* Generates bytecode to parse a single non-lazy message field. */
10091static void generate_msgfield(compiler *c, const upb_fielddef *f,
10092 upb_pbdecodermethod *method) {
10093 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
10094 const upb_pbdecodermethod *sub_m = find_submethod(c, method, f);
10095 int wire_type;
10096
10097 if (!sub_m) {
10098 /* Don't emit any code for this field at all; it will be parsed as an
Paul Yange0e54662016-09-15 11:09:01 -070010099 * unknown field.
10100 *
10101 * TODO(haberman): we should change this to parse it as a string field
10102 * instead. It will probably be faster, but more importantly, once we
10103 * start vending unknown fields, a field shouldn't be treated as unknown
10104 * just because it doesn't have subhandlers registered. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010105 return;
10106 }
10107
10108 label(c, LABEL_FIELD);
10109
10110 wire_type =
10111 (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE)
10112 ? UPB_WIRE_TYPE_DELIMITED
10113 : UPB_WIRE_TYPE_START_GROUP;
10114
10115 if (upb_fielddef_isseq(f)) {
10116 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10117 putchecktag(c, f, wire_type, LABEL_DISPATCH);
10118 dispatchtarget(c, method, f, wire_type);
10119 putop(c, OP_PUSHTAGDELIM, 0);
10120 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
10121 label(c, LABEL_LOOPSTART);
10122 putpush(c, f);
10123 putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
10124 putop(c, OP_CALL, sub_m);
10125 putop(c, OP_POP);
10126 maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
10127 if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
10128 putop(c, OP_SETDELIM);
10129 }
10130 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
10131 putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
10132 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
10133 label(c, LABEL_LOOPBREAK);
10134 putop(c, OP_POP);
10135 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
10136 } else {
10137 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10138 putchecktag(c, f, wire_type, LABEL_DISPATCH);
10139 dispatchtarget(c, method, f, wire_type);
10140 putpush(c, f);
10141 putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
10142 putop(c, OP_CALL, sub_m);
10143 putop(c, OP_POP);
10144 maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
10145 if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
10146 putop(c, OP_SETDELIM);
10147 }
10148 }
10149}
10150
10151/* Generates bytecode to parse a single string or lazy submessage field. */
10152static void generate_delimfield(compiler *c, const upb_fielddef *f,
10153 upb_pbdecodermethod *method) {
10154 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
10155
10156 label(c, LABEL_FIELD);
10157 if (upb_fielddef_isseq(f)) {
10158 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10159 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
10160 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
10161 putop(c, OP_PUSHTAGDELIM, 0);
10162 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
10163 label(c, LABEL_LOOPSTART);
10164 putop(c, OP_PUSHLENDELIM);
10165 putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
10166 /* Need to emit even if no handler to skip past the string. */
10167 putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010168 maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
Paul Yangc4f2a922019-01-17 10:18:43 -080010169 putop(c, OP_POP);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010170 putop(c, OP_SETDELIM);
10171 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
10172 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_LOOPBREAK);
10173 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
10174 label(c, LABEL_LOOPBREAK);
10175 putop(c, OP_POP);
10176 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
10177 } else {
10178 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10179 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
10180 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
10181 putop(c, OP_PUSHLENDELIM);
10182 putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
10183 putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010184 maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
Paul Yangc4f2a922019-01-17 10:18:43 -080010185 putop(c, OP_POP);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010186 putop(c, OP_SETDELIM);
10187 }
10188}
10189
10190/* Generates bytecode to parse a single primitive field. */
10191static void generate_primitivefield(compiler *c, const upb_fielddef *f,
10192 upb_pbdecodermethod *method) {
10193 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
10194 upb_descriptortype_t descriptor_type = upb_fielddef_descriptortype(f);
10195 opcode parse_type;
10196 upb_selector_t sel;
10197 int wire_type;
10198
10199 label(c, LABEL_FIELD);
10200
10201 /* From a decoding perspective, ENUM is the same as INT32. */
10202 if (descriptor_type == UPB_DESCRIPTOR_TYPE_ENUM)
10203 descriptor_type = UPB_DESCRIPTOR_TYPE_INT32;
10204
10205 parse_type = (opcode)descriptor_type;
10206
10207 /* TODO(haberman): generate packed or non-packed first depending on "packed"
10208 * setting in the fielddef. This will favor (in speed) whichever was
10209 * specified. */
10210
Paul Yange0e54662016-09-15 11:09:01 -070010211 UPB_ASSERT((int)parse_type >= 0 && parse_type <= OP_MAX);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010212 sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
10213 wire_type = upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
10214 if (upb_fielddef_isseq(f)) {
10215 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10216 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
10217 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
10218 putop(c, OP_PUSHLENDELIM);
10219 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Packed */
10220 label(c, LABEL_LOOPSTART);
10221 putop(c, parse_type, sel);
10222 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
10223 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
10224 dispatchtarget(c, method, f, wire_type);
10225 putop(c, OP_PUSHTAGDELIM, 0);
10226 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Non-packed */
10227 label(c, LABEL_LOOPSTART);
10228 putop(c, parse_type, sel);
10229 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
10230 putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
10231 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
10232 label(c, LABEL_LOOPBREAK);
10233 putop(c, OP_POP); /* Packed and non-packed join. */
10234 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
10235 putop(c, OP_SETDELIM); /* Could remove for non-packed by dup ENDSEQ. */
10236 } else {
10237 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10238 putchecktag(c, f, wire_type, LABEL_DISPATCH);
10239 dispatchtarget(c, method, f, wire_type);
10240 putop(c, parse_type, sel);
10241 }
10242}
10243
10244/* Adds bytecode for parsing the given message to the given decoderplan,
10245 * while adding all dispatch targets to this message's dispatch table. */
10246static void compile_method(compiler *c, upb_pbdecodermethod *method) {
10247 const upb_handlers *h;
10248 const upb_msgdef *md;
10249 uint32_t* start_pc;
10250 upb_msg_field_iter i;
10251 upb_value val;
10252
Paul Yange0e54662016-09-15 11:09:01 -070010253 UPB_ASSERT(method);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010254
10255 /* Clear all entries in the dispatch table. */
10256 upb_inttable_uninit(&method->dispatch);
10257 upb_inttable_init(&method->dispatch, UPB_CTYPE_UINT64);
10258
10259 h = upb_pbdecodermethod_desthandlers(method);
10260 md = upb_handlers_msgdef(h);
10261
10262 method->code_base.ofs = pcofs(c);
10263 putop(c, OP_SETDISPATCH, &method->dispatch);
10264 putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h);
10265 label(c, LABEL_FIELD);
10266 start_pc = c->pc;
10267 for(upb_msg_field_begin(&i, md);
10268 !upb_msg_field_done(&i);
10269 upb_msg_field_next(&i)) {
10270 const upb_fielddef *f = upb_msg_iter_field(&i);
10271 upb_fieldtype_t type = upb_fielddef_type(f);
10272
10273 if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) {
10274 generate_msgfield(c, f, method);
10275 } else if (type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES ||
10276 type == UPB_TYPE_MESSAGE) {
10277 generate_delimfield(c, f, method);
10278 } else {
10279 generate_primitivefield(c, f, method);
10280 }
10281 }
10282
10283 /* If there were no fields, or if no handlers were defined, we need to
10284 * generate a non-empty loop body so that we can at least dispatch for unknown
10285 * fields and check for the end of the message. */
10286 if (c->pc == start_pc) {
10287 /* Check for end-of-message. */
10288 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
10289 /* Unconditionally dispatch. */
10290 putop(c, OP_DISPATCH, 0);
10291 }
10292
10293 /* For now we just loop back to the last field of the message (or if none,
10294 * the DISPATCH opcode for the message). */
10295 putop(c, OP_BRANCH, -LABEL_FIELD);
10296
10297 /* Insert both a label and a dispatch table entry for this end-of-msg. */
10298 label(c, LABEL_ENDMSG);
10299 val = upb_value_uint64(pcofs(c) - method->code_base.ofs);
10300 upb_inttable_insert(&method->dispatch, DISPATCH_ENDMSG, val);
10301
10302 putsel(c, OP_ENDMSG, UPB_ENDMSG_SELECTOR, h);
10303 putop(c, OP_RET);
10304
10305 upb_inttable_compact(&method->dispatch);
10306}
10307
10308/* Populate "methods" with new upb_pbdecodermethod objects reachable from "h".
10309 * Returns the method for these handlers.
10310 *
10311 * Generates a new method for every destination handlers reachable from "h". */
10312static void find_methods(compiler *c, const upb_handlers *h) {
10313 upb_value v;
10314 upb_msg_field_iter i;
10315 const upb_msgdef *md;
10316
10317 if (upb_inttable_lookupptr(&c->group->methods, h, &v))
10318 return;
10319 newmethod(h, c->group);
10320
10321 /* Find submethods. */
10322 md = upb_handlers_msgdef(h);
10323 for(upb_msg_field_begin(&i, md);
10324 !upb_msg_field_done(&i);
10325 upb_msg_field_next(&i)) {
10326 const upb_fielddef *f = upb_msg_iter_field(&i);
10327 const upb_handlers *sub_h;
10328 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
10329 (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) {
10330 /* We only generate a decoder method for submessages with handlers.
10331 * Others will be parsed as unknown fields. */
10332 find_methods(c, sub_h);
10333 }
10334 }
10335}
10336
10337/* (Re-)compile bytecode for all messages in "msgs."
10338 * Overwrites any existing bytecode in "c". */
10339static void compile_methods(compiler *c) {
10340 upb_inttable_iter i;
10341
10342 /* Start over at the beginning of the bytecode. */
10343 c->pc = c->group->bytecode;
10344
10345 upb_inttable_begin(&i, &c->group->methods);
10346 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
10347 upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
10348 compile_method(c, method);
10349 }
10350}
10351
10352static void set_bytecode_handlers(mgroup *g) {
10353 upb_inttable_iter i;
10354 upb_inttable_begin(&i, &g->methods);
10355 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
10356 upb_pbdecodermethod *m = upb_value_getptr(upb_inttable_iter_value(&i));
10357 upb_byteshandler *h = &m->input_handler_;
10358
10359 m->code_base.ptr = g->bytecode + m->code_base.ofs;
10360
10361 upb_byteshandler_setstartstr(h, upb_pbdecoder_startbc, m->code_base.ptr);
10362 upb_byteshandler_setstring(h, upb_pbdecoder_decode, g);
10363 upb_byteshandler_setendstr(h, upb_pbdecoder_end, m);
10364 }
10365}
10366
10367
10368/* JIT setup. *****************************************************************/
10369
10370#ifdef UPB_USE_JIT_X64
10371
10372static void sethandlers(mgroup *g, bool allowjit) {
10373 g->jit_code = NULL;
10374 if (allowjit) {
10375 /* Compile byte-code into machine code, create handlers. */
10376 upb_pbdecoder_jit(g);
10377 } else {
10378 set_bytecode_handlers(g);
10379 }
10380}
10381
10382#else /* UPB_USE_JIT_X64 */
10383
10384static void sethandlers(mgroup *g, bool allowjit) {
10385 /* No JIT compiled in; use bytecode handlers unconditionally. */
10386 UPB_UNUSED(allowjit);
10387 set_bytecode_handlers(g);
10388}
10389
10390#endif /* UPB_USE_JIT_X64 */
10391
10392
10393/* TODO(haberman): allow this to be constructed for an arbitrary set of dest
10394 * handlers and other mgroups (but verify we have a transitive closure). */
10395const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
10396 const void *owner) {
10397 mgroup *g;
10398 compiler *c;
10399
10400 UPB_UNUSED(allowjit);
Paul Yange0e54662016-09-15 11:09:01 -070010401 UPB_ASSERT(upb_handlers_isfrozen(dest));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010402
10403 g = newgroup(owner);
10404 c = newcompiler(g, lazy);
10405 find_methods(c, dest);
10406
10407 /* We compile in two passes:
10408 * 1. all messages are assigned relative offsets from the beginning of the
10409 * bytecode (saved in method->code_base).
10410 * 2. forwards OP_CALL instructions can be correctly linked since message
10411 * offsets have been previously assigned.
10412 *
10413 * Could avoid the second pass by linking OP_CALL instructions somehow. */
10414 compile_methods(c);
10415 compile_methods(c);
10416 g->bytecode_end = c->pc;
10417 freecompiler(c);
10418
10419#ifdef UPB_DUMP_BYTECODE
10420 {
Paul Yange0e54662016-09-15 11:09:01 -070010421 FILE *f = fopen("/tmp/upb-bytecode", "w");
10422 UPB_ASSERT(f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010423 dumpbc(g->bytecode, g->bytecode_end, stderr);
10424 dumpbc(g->bytecode, g->bytecode_end, f);
10425 fclose(f);
Paul Yange0e54662016-09-15 11:09:01 -070010426
10427 f = fopen("/tmp/upb-bytecode.bin", "wb");
10428 UPB_ASSERT(f);
10429 fwrite(g->bytecode, 1, g->bytecode_end - g->bytecode, f);
10430 fclose(f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010431 }
10432#endif
10433
10434 sethandlers(g, allowjit);
10435 return g;
10436}
10437
10438
10439/* upb_pbcodecache ************************************************************/
10440
10441void upb_pbcodecache_init(upb_pbcodecache *c) {
10442 upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR);
10443 c->allow_jit_ = true;
10444}
10445
10446void upb_pbcodecache_uninit(upb_pbcodecache *c) {
10447 upb_inttable_iter i;
10448 upb_inttable_begin(&i, &c->groups);
10449 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
10450 const mgroup *group = upb_value_getconstptr(upb_inttable_iter_value(&i));
10451 mgroup_unref(group, c);
10452 }
10453 upb_inttable_uninit(&c->groups);
10454}
10455
10456bool upb_pbcodecache_allowjit(const upb_pbcodecache *c) {
10457 return c->allow_jit_;
10458}
10459
10460bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow) {
10461 if (upb_inttable_count(&c->groups) > 0)
10462 return false;
10463 c->allow_jit_ = allow;
10464 return true;
10465}
10466
10467const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
10468 upb_pbcodecache *c, const upb_pbdecodermethodopts *opts) {
10469 upb_value v;
10470 bool ok;
10471
10472 /* Right now we build a new DecoderMethod every time.
10473 * TODO(haberman): properly cache methods by their true key. */
10474 const mgroup *g = mgroup_new(opts->handlers, c->allow_jit_, opts->lazy, c);
10475 upb_inttable_push(&c->groups, upb_value_constptr(g));
10476
10477 ok = upb_inttable_lookupptr(&g->methods, opts->handlers, &v);
Paul Yange0e54662016-09-15 11:09:01 -070010478 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010479 return upb_value_getptr(v);
10480}
10481
10482
10483/* upb_pbdecodermethodopts ****************************************************/
10484
10485void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
10486 const upb_handlers *h) {
10487 opts->handlers = h;
10488 opts->lazy = false;
10489}
10490
10491void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
10492 opts->lazy = lazy;
10493}
10494/*
10495** upb::Decoder (Bytecode Decoder VM)
10496**
10497** Bytecode must previously have been generated using the bytecode compiler in
10498** compile_decoder.c. This decoder then walks through the bytecode op-by-op to
10499** parse the input.
10500**
10501** Decoding is fully resumable; we just keep a pointer to the current bytecode
10502** instruction and resume from there. A fair amount of the logic here is to
10503** handle the fact that values can span buffer seams and we have to be able to
10504** be capable of suspending/resuming from any byte in the stream. This
10505** sometimes requires keeping a few trailing bytes from the last buffer around
10506** in the "residual" buffer.
10507*/
10508
10509#include <inttypes.h>
10510#include <stddef.h>
10511
10512#ifdef UPB_DUMP_BYTECODE
10513#include <stdio.h>
10514#endif
10515
10516#define CHECK_SUSPEND(x) if (!(x)) return upb_pbdecoder_suspend(d);
10517
10518/* Error messages that are shared between the bytecode and JIT decoders. */
10519const char *kPbDecoderStackOverflow = "Nesting too deep.";
10520const char *kPbDecoderSubmessageTooLong =
10521 "Submessage end extends past enclosing submessage.";
10522
10523/* Error messages shared within this file. */
10524static const char *kUnterminatedVarint = "Unterminated varint.";
10525
10526/* upb_pbdecoder **************************************************************/
10527
10528static opcode halt = OP_HALT;
10529
Paul Yange0e54662016-09-15 11:09:01 -070010530/* A dummy character we can point to when the user passes us a NULL buffer.
10531 * We need this because in C (NULL + 0) and (NULL - NULL) are undefined
10532 * behavior, which would invalidate functions like curbufleft(). */
10533static const char dummy_char;
10534
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010535/* Whether an op consumes any of the input buffer. */
10536static bool consumes_input(opcode op) {
10537 switch (op) {
10538 case OP_SETDISPATCH:
10539 case OP_STARTMSG:
10540 case OP_ENDMSG:
10541 case OP_STARTSEQ:
10542 case OP_ENDSEQ:
10543 case OP_STARTSUBMSG:
10544 case OP_ENDSUBMSG:
10545 case OP_STARTSTR:
10546 case OP_ENDSTR:
10547 case OP_PUSHTAGDELIM:
10548 case OP_POP:
10549 case OP_SETDELIM:
10550 case OP_SETBIGGROUPNUM:
10551 case OP_CHECKDELIM:
10552 case OP_CALL:
10553 case OP_RET:
10554 case OP_BRANCH:
10555 return false;
10556 default:
10557 return true;
10558 }
10559}
10560
10561static size_t stacksize(upb_pbdecoder *d, size_t entries) {
10562 UPB_UNUSED(d);
10563 return entries * sizeof(upb_pbdecoder_frame);
10564}
10565
10566static size_t callstacksize(upb_pbdecoder *d, size_t entries) {
10567 UPB_UNUSED(d);
10568
10569#ifdef UPB_USE_JIT_X64
10570 if (d->method_->is_native_) {
10571 /* Each native stack frame needs two pointers, plus we need a few frames for
10572 * the enter/exit trampolines. */
10573 size_t ret = entries * sizeof(void*) * 2;
10574 ret += sizeof(void*) * 10;
10575 return ret;
10576 }
10577#endif
10578
10579 return entries * sizeof(uint32_t*);
10580}
10581
10582
10583static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
10584
10585/* It's unfortunate that we have to micro-manage the compiler with
10586 * UPB_FORCEINLINE and UPB_NOINLINE, especially since this tuning is necessarily
10587 * specific to one hardware configuration. But empirically on a Core i7,
10588 * performance increases 30-50% with these annotations. Every instance where
10589 * these appear, gcc 4.2.1 made the wrong decision and degraded performance in
10590 * benchmarks. */
10591
10592static void seterr(upb_pbdecoder *d, const char *msg) {
10593 upb_status status = UPB_STATUS_INIT;
10594 upb_status_seterrmsg(&status, msg);
10595 upb_env_reporterror(d->env, &status);
10596}
10597
10598void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
10599 seterr(d, msg);
10600}
10601
10602
10603/* Buffering ******************************************************************/
10604
10605/* We operate on one buffer at a time, which is either the user's buffer passed
10606 * to our "decode" callback or some residual bytes from the previous buffer. */
10607
10608/* How many bytes can be safely read from d->ptr without reading past end-of-buf
10609 * or past the current delimited end. */
10610static size_t curbufleft(const upb_pbdecoder *d) {
Paul Yange0e54662016-09-15 11:09:01 -070010611 UPB_ASSERT(d->data_end >= d->ptr);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010612 return d->data_end - d->ptr;
10613}
10614
10615/* How many bytes are available before end-of-buffer. */
10616static size_t bufleft(const upb_pbdecoder *d) {
10617 return d->end - d->ptr;
10618}
10619
10620/* Overall stream offset of d->ptr. */
10621uint64_t offset(const upb_pbdecoder *d) {
10622 return d->bufstart_ofs + (d->ptr - d->buf);
10623}
10624
10625/* How many bytes are available before the end of this delimited region. */
10626size_t delim_remaining(const upb_pbdecoder *d) {
10627 return d->top->end_ofs - offset(d);
10628}
10629
10630/* Advances d->ptr. */
10631static void advance(upb_pbdecoder *d, size_t len) {
Paul Yange0e54662016-09-15 11:09:01 -070010632 UPB_ASSERT(curbufleft(d) >= len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010633 d->ptr += len;
10634}
10635
10636static bool in_buf(const char *p, const char *buf, const char *end) {
10637 return p >= buf && p <= end;
10638}
10639
10640static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
10641 return in_buf(p, d->residual, d->residual_end);
10642}
10643
10644/* Calculates the delim_end value, which is affected by both the current buffer
10645 * and the parsing stack, so must be called whenever either is updated. */
10646static void set_delim_end(upb_pbdecoder *d) {
10647 size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
10648 if (delim_ofs <= (size_t)(d->end - d->buf)) {
10649 d->delim_end = d->buf + delim_ofs;
10650 d->data_end = d->delim_end;
10651 } else {
10652 d->data_end = d->end;
10653 d->delim_end = NULL;
10654 }
10655}
10656
10657static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end) {
10658 d->ptr = buf;
10659 d->buf = buf;
10660 d->end = end;
10661 set_delim_end(d);
10662}
10663
10664static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) {
Paul Yange0e54662016-09-15 11:09:01 -070010665 UPB_ASSERT(curbufleft(d) == 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010666 d->bufstart_ofs += (d->end - d->buf);
10667 switchtobuf(d, buf, buf + len);
10668}
10669
10670static void checkpoint(upb_pbdecoder *d) {
10671 /* The assertion here is in the interests of efficiency, not correctness.
10672 * We are trying to ensure that we don't checkpoint() more often than
10673 * necessary. */
Paul Yange0e54662016-09-15 11:09:01 -070010674 UPB_ASSERT(d->checkpoint != d->ptr);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010675 d->checkpoint = d->ptr;
10676}
10677
10678/* Skips "bytes" bytes in the stream, which may be more than available. If we
10679 * skip more bytes than are available, we return a long read count to the caller
10680 * indicating how many bytes can be skipped over before passing actual data
10681 * again. Skipped bytes can pass a NULL buffer and the decoder guarantees they
10682 * won't actually be read.
10683 */
10684static int32_t skip(upb_pbdecoder *d, size_t bytes) {
Paul Yange0e54662016-09-15 11:09:01 -070010685 UPB_ASSERT(!in_residual_buf(d, d->ptr) || d->size_param == 0);
10686 UPB_ASSERT(d->skip == 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010687 if (bytes > delim_remaining(d)) {
10688 seterr(d, "Skipped value extended beyond enclosing submessage.");
10689 return upb_pbdecoder_suspend(d);
Paul Yange0e54662016-09-15 11:09:01 -070010690 } else if (bufleft(d) >= bytes) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010691 /* Skipped data is all in current buffer, and more is still available. */
10692 advance(d, bytes);
10693 d->skip = 0;
10694 return DECODE_OK;
10695 } else {
10696 /* Skipped data extends beyond currently available buffers. */
10697 d->pc = d->last;
10698 d->skip = bytes - curbufleft(d);
10699 d->bufstart_ofs += (d->end - d->buf);
10700 d->residual_end = d->residual;
10701 switchtobuf(d, d->residual, d->residual_end);
10702 return d->size_param + d->skip;
10703 }
10704}
10705
10706
10707/* Resumes the decoder from an initial state or from a previous suspend. */
10708int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
10709 size_t size, const upb_bufhandle *handle) {
10710 UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */
10711
Paul Yange0e54662016-09-15 11:09:01 -070010712 /* d->skip and d->residual_end could probably elegantly be represented
10713 * as a single variable, to more easily represent this invariant. */
10714 UPB_ASSERT(!(d->skip && d->residual_end > d->residual));
10715
10716 /* We need to remember the original size_param, so that the value we return
10717 * is relative to it, even if we do some skipping first. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010718 d->size_param = size;
10719 d->handle = handle;
10720
Paul Yange0e54662016-09-15 11:09:01 -070010721 /* Have to handle this case specially (ie. not with skip()) because the user
10722 * is allowed to pass a NULL buffer here, which won't allow us to safely
10723 * calculate a d->end or use our normal functions like curbufleft(). */
10724 if (d->skip && d->skip >= size) {
10725 d->skip -= size;
10726 d->bufstart_ofs += size;
10727 buf = &dummy_char;
10728 size = 0;
10729
10730 /* We can't just return now, because we might need to execute some ops
10731 * like CHECKDELIM, which could call some callbacks and pop the stack. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010732 }
10733
Paul Yange0e54662016-09-15 11:09:01 -070010734 /* We need to pretend that this was the actual buffer param, since some of the
10735 * calculations assume that d->ptr/d->buf is relative to this. */
10736 d->buf_param = buf;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010737
10738 if (!buf) {
10739 /* NULL buf is ok if its entire span is covered by the "skip" above, but
10740 * by this point we know that "skip" doesn't cover the buffer. */
10741 seterr(d, "Passed NULL buffer over non-skippable region.");
10742 return upb_pbdecoder_suspend(d);
10743 }
10744
Paul Yange0e54662016-09-15 11:09:01 -070010745 if (d->residual_end > d->residual) {
10746 /* We have residual bytes from the last buffer. */
10747 UPB_ASSERT(d->ptr == d->residual);
10748 } else {
10749 switchtobuf(d, buf, buf + size);
10750 }
10751
10752 d->checkpoint = d->ptr;
10753
10754 /* Handle skips that don't cover the whole buffer (as above). */
10755 if (d->skip) {
10756 size_t skip_bytes = d->skip;
10757 d->skip = 0;
10758 CHECK_RETURN(skip(d, skip_bytes));
10759 checkpoint(d);
10760 }
10761
10762 /* If we're inside an unknown group, continue to parse unknown values. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010763 if (d->top->groupnum < 0) {
10764 CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0));
Paul Yange0e54662016-09-15 11:09:01 -070010765 checkpoint(d);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010766 }
10767
10768 return DECODE_OK;
10769}
10770
10771/* Suspends the decoder at the last checkpoint, without saving any residual
10772 * bytes. If there are any unconsumed bytes, returns a short byte count. */
10773size_t upb_pbdecoder_suspend(upb_pbdecoder *d) {
10774 d->pc = d->last;
10775 if (d->checkpoint == d->residual) {
10776 /* Checkpoint was in residual buf; no user bytes were consumed. */
10777 d->ptr = d->residual;
10778 return 0;
10779 } else {
Paul Yange0e54662016-09-15 11:09:01 -070010780 size_t ret = d->size_param - (d->end - d->checkpoint);
10781 UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
10782 UPB_ASSERT(d->buf == d->buf_param || d->buf == &dummy_char);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010783
Paul Yange0e54662016-09-15 11:09:01 -070010784 d->bufstart_ofs += (d->checkpoint - d->buf);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010785 d->residual_end = d->residual;
10786 switchtobuf(d, d->residual, d->residual_end);
Paul Yange0e54662016-09-15 11:09:01 -070010787 return ret;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010788 }
10789}
10790
10791/* Suspends the decoder at the last checkpoint, and saves any unconsumed
10792 * bytes in our residual buffer. This is necessary if we need more user
10793 * bytes to form a complete value, which might not be contiguous in the
10794 * user's buffers. Always consumes all user bytes. */
10795static size_t suspend_save(upb_pbdecoder *d) {
10796 /* We hit end-of-buffer before we could parse a full value.
10797 * Save any unconsumed bytes (if any) to the residual buffer. */
10798 d->pc = d->last;
10799
10800 if (d->checkpoint == d->residual) {
10801 /* Checkpoint was in residual buf; append user byte(s) to residual buf. */
Paul Yange0e54662016-09-15 11:09:01 -070010802 UPB_ASSERT((d->residual_end - d->residual) + d->size_param <=
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010803 sizeof(d->residual));
10804 if (!in_residual_buf(d, d->ptr)) {
10805 d->bufstart_ofs -= (d->residual_end - d->residual);
10806 }
10807 memcpy(d->residual_end, d->buf_param, d->size_param);
10808 d->residual_end += d->size_param;
10809 } else {
10810 /* Checkpoint was in user buf; old residual bytes not needed. */
10811 size_t save;
Paul Yange0e54662016-09-15 11:09:01 -070010812 UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010813
10814 d->ptr = d->checkpoint;
10815 save = curbufleft(d);
Paul Yange0e54662016-09-15 11:09:01 -070010816 UPB_ASSERT(save <= sizeof(d->residual));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010817 memcpy(d->residual, d->ptr, save);
10818 d->residual_end = d->residual + save;
10819 d->bufstart_ofs = offset(d);
10820 }
10821
10822 switchtobuf(d, d->residual, d->residual_end);
10823 return d->size_param;
10824}
10825
10826/* Copies the next "bytes" bytes into "buf" and advances the stream.
10827 * Requires that this many bytes are available in the current buffer. */
10828UPB_FORCEINLINE static void consumebytes(upb_pbdecoder *d, void *buf,
10829 size_t bytes) {
Paul Yange0e54662016-09-15 11:09:01 -070010830 UPB_ASSERT(bytes <= curbufleft(d));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010831 memcpy(buf, d->ptr, bytes);
10832 advance(d, bytes);
10833}
10834
10835/* Slow path for getting the next "bytes" bytes, regardless of whether they are
10836 * available in the current buffer or not. Returns a status code as described
10837 * in decoder.int.h. */
10838UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
10839 size_t bytes) {
10840 const size_t avail = curbufleft(d);
10841 consumebytes(d, buf, avail);
10842 bytes -= avail;
Paul Yange0e54662016-09-15 11:09:01 -070010843 UPB_ASSERT(bytes > 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010844 if (in_residual_buf(d, d->ptr)) {
10845 advancetobuf(d, d->buf_param, d->size_param);
10846 }
10847 if (curbufleft(d) >= bytes) {
10848 consumebytes(d, (char *)buf + avail, bytes);
10849 return DECODE_OK;
10850 } else if (d->data_end == d->delim_end) {
10851 seterr(d, "Submessage ended in the middle of a value or group");
10852 return upb_pbdecoder_suspend(d);
10853 } else {
10854 return suspend_save(d);
10855 }
10856}
10857
10858/* Gets the next "bytes" bytes, regardless of whether they are available in the
10859 * current buffer or not. Returns a status code as described in decoder.int.h.
10860 */
10861UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf,
10862 size_t bytes) {
10863 if (curbufleft(d) >= bytes) {
10864 /* Buffer has enough data to satisfy. */
10865 consumebytes(d, buf, bytes);
10866 return DECODE_OK;
10867 } else {
10868 return getbytes_slow(d, buf, bytes);
10869 }
10870}
10871
10872UPB_NOINLINE static size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
10873 size_t bytes) {
10874 size_t ret = curbufleft(d);
10875 memcpy(buf, d->ptr, ret);
10876 if (in_residual_buf(d, d->ptr)) {
10877 size_t copy = UPB_MIN(bytes - ret, d->size_param);
10878 memcpy((char *)buf + ret, d->buf_param, copy);
10879 ret += copy;
10880 }
10881 return ret;
10882}
10883
10884UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf,
10885 size_t bytes) {
10886 if (curbufleft(d) >= bytes) {
10887 memcpy(buf, d->ptr, bytes);
10888 return bytes;
10889 } else {
10890 return peekbytes_slow(d, buf, bytes);
10891 }
10892}
10893
10894
10895/* Decoding of wire types *****************************************************/
10896
10897/* Slow path for decoding a varint from the current buffer position.
10898 * Returns a status code as described in decoder.int.h. */
10899UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
10900 uint64_t *u64) {
10901 uint8_t byte = 0x80;
10902 int bitpos;
10903 *u64 = 0;
10904 for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
Paul Yange0e54662016-09-15 11:09:01 -070010905 CHECK_RETURN(getbytes(d, &byte, 1));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070010906 *u64 |= (uint64_t)(byte & 0x7F) << bitpos;
10907 }
10908 if(bitpos == 70 && (byte & 0x80)) {
10909 seterr(d, kUnterminatedVarint);
10910 return upb_pbdecoder_suspend(d);
10911 }
10912 return DECODE_OK;
10913}
10914
10915/* Decodes a varint from the current buffer position.
10916 * Returns a status code as described in decoder.int.h. */
10917UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
10918 if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
10919 *u64 = *d->ptr;
10920 advance(d, 1);
10921 return DECODE_OK;
10922 } else if (curbufleft(d) >= 10) {
10923 /* Fast case. */
10924 upb_decoderet r = upb_vdecode_fast(d->ptr);
10925 if (r.p == NULL) {
10926 seterr(d, kUnterminatedVarint);
10927 return upb_pbdecoder_suspend(d);
10928 }
10929 advance(d, r.p - d->ptr);
10930 *u64 = r.val;
10931 return DECODE_OK;
10932 } else {
10933 /* Slow case -- varint spans buffer seam. */
10934 return upb_pbdecoder_decode_varint_slow(d, u64);
10935 }
10936}
10937
10938/* Decodes a 32-bit varint from the current buffer position.
10939 * Returns a status code as described in decoder.int.h. */
10940UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
10941 uint64_t u64;
10942 int32_t ret = decode_varint(d, &u64);
10943 if (ret >= 0) return ret;
10944 if (u64 > UINT32_MAX) {
10945 seterr(d, "Unterminated 32-bit varint");
10946 /* TODO(haberman) guarantee that this function return is >= 0 somehow,
10947 * so we know this path will always be treated as error by our caller.
10948 * Right now the size_t -> int32_t can overflow and produce negative values.
10949 */
10950 *u32 = 0;
10951 return upb_pbdecoder_suspend(d);
10952 }
10953 *u32 = u64;
10954 return DECODE_OK;
10955}
10956
10957/* Decodes a fixed32 from the current buffer position.
10958 * Returns a status code as described in decoder.int.h.
10959 * TODO: proper byte swapping for big-endian machines. */
10960UPB_FORCEINLINE static int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
10961 return getbytes(d, u32, 4);
10962}
10963
10964/* Decodes a fixed64 from the current buffer position.
10965 * Returns a status code as described in decoder.int.h.
10966 * TODO: proper byte swapping for big-endian machines. */
10967UPB_FORCEINLINE static int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
10968 return getbytes(d, u64, 8);
10969}
10970
10971/* Non-static versions of the above functions.
10972 * These are called by the JIT for fallback paths. */
10973int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) {
10974 return decode_fixed32(d, u32);
10975}
10976
10977int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) {
10978 return decode_fixed64(d, u64);
10979}
10980
10981static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; }
10982static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; }
10983
10984/* Pushes a frame onto the decoder stack. */
10985static bool decoder_push(upb_pbdecoder *d, uint64_t end) {
10986 upb_pbdecoder_frame *fr = d->top;
10987
10988 if (end > fr->end_ofs) {
10989 seterr(d, kPbDecoderSubmessageTooLong);
10990 return false;
10991 } else if (fr == d->limit) {
10992 seterr(d, kPbDecoderStackOverflow);
10993 return false;
10994 }
10995
10996 fr++;
10997 fr->end_ofs = end;
10998 fr->dispatch = NULL;
10999 fr->groupnum = 0;
11000 d->top = fr;
11001 return true;
11002}
11003
11004static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
11005 /* While we expect to see an "end" tag (either ENDGROUP or a non-sequence
11006 * field number) prior to hitting any enclosing submessage end, pushing our
11007 * existing delim end prevents us from continuing to parse values from a
11008 * corrupt proto that doesn't give us an END tag in time. */
11009 if (!decoder_push(d, d->top->end_ofs))
11010 return false;
11011 d->top->groupnum = arg;
11012 return true;
11013}
11014
11015/* Pops a frame from the decoder stack. */
11016static void decoder_pop(upb_pbdecoder *d) { d->top--; }
11017
11018UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
11019 uint64_t expected) {
11020 uint64_t data = 0;
11021 size_t bytes = upb_value_size(expected);
11022 size_t read = peekbytes(d, &data, bytes);
11023 if (read == bytes && data == expected) {
11024 /* Advance past matched bytes. */
11025 int32_t ok = getbytes(d, &data, read);
Paul Yange0e54662016-09-15 11:09:01 -070011026 UPB_ASSERT(ok < 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011027 return DECODE_OK;
11028 } else if (read < bytes && memcmp(&data, &expected, read) == 0) {
11029 return suspend_save(d);
11030 } else {
11031 return DECODE_MISMATCH;
11032 }
11033}
11034
11035int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
11036 uint8_t wire_type) {
11037 if (fieldnum >= 0)
11038 goto have_tag;
11039
11040 while (true) {
11041 uint32_t tag;
11042 CHECK_RETURN(decode_v32(d, &tag));
11043 wire_type = tag & 0x7;
11044 fieldnum = tag >> 3;
11045
11046have_tag:
11047 if (fieldnum == 0) {
11048 seterr(d, "Saw invalid field number (0)");
11049 return upb_pbdecoder_suspend(d);
11050 }
11051
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011052 switch (wire_type) {
11053 case UPB_WIRE_TYPE_32BIT:
11054 CHECK_RETURN(skip(d, 4));
11055 break;
11056 case UPB_WIRE_TYPE_64BIT:
11057 CHECK_RETURN(skip(d, 8));
11058 break;
11059 case UPB_WIRE_TYPE_VARINT: {
11060 uint64_t u64;
11061 CHECK_RETURN(decode_varint(d, &u64));
11062 break;
11063 }
11064 case UPB_WIRE_TYPE_DELIMITED: {
11065 uint32_t len;
11066 CHECK_RETURN(decode_v32(d, &len));
11067 CHECK_RETURN(skip(d, len));
11068 break;
11069 }
11070 case UPB_WIRE_TYPE_START_GROUP:
11071 CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
11072 break;
11073 case UPB_WIRE_TYPE_END_GROUP:
11074 if (fieldnum == -d->top->groupnum) {
11075 decoder_pop(d);
11076 } else if (fieldnum == d->top->groupnum) {
11077 return DECODE_ENDGROUP;
11078 } else {
11079 seterr(d, "Unmatched ENDGROUP tag.");
11080 return upb_pbdecoder_suspend(d);
11081 }
11082 break;
11083 default:
11084 seterr(d, "Invalid wire type");
11085 return upb_pbdecoder_suspend(d);
11086 }
11087
11088 if (d->top->groupnum >= 0) {
Paul Yang60327462017-10-09 12:39:13 -070011089 /* TODO: More code needed for handling unknown groups. */
11090 upb_sink_putunknown(&d->top->sink, d->checkpoint, d->ptr - d->checkpoint);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011091 return DECODE_OK;
11092 }
11093
11094 /* Unknown group -- continue looping over unknown fields. */
11095 checkpoint(d);
11096 }
11097}
11098
11099static void goto_endmsg(upb_pbdecoder *d) {
11100 upb_value v;
11101 bool found = upb_inttable_lookup32(d->top->dispatch, DISPATCH_ENDMSG, &v);
Paul Yange0e54662016-09-15 11:09:01 -070011102 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011103 d->pc = d->top->base + upb_value_getuint64(v);
11104}
11105
11106/* Parses a tag and jumps to the corresponding bytecode instruction for this
11107 * field.
11108 *
11109 * If the tag is unknown (or the wire type doesn't match), parses the field as
11110 * unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode
11111 * instruction for the end of message. */
11112static int32_t dispatch(upb_pbdecoder *d) {
11113 upb_inttable *dispatch = d->top->dispatch;
11114 uint32_t tag;
11115 uint8_t wire_type;
11116 uint32_t fieldnum;
11117 upb_value val;
11118 int32_t retval;
11119
11120 /* Decode tag. */
11121 CHECK_RETURN(decode_v32(d, &tag));
11122 wire_type = tag & 0x7;
11123 fieldnum = tag >> 3;
11124
11125 /* Lookup tag. Because of packed/non-packed compatibility, we have to
11126 * check the wire type against two possibilities. */
11127 if (fieldnum != DISPATCH_ENDMSG &&
11128 upb_inttable_lookup32(dispatch, fieldnum, &val)) {
11129 uint64_t v = upb_value_getuint64(val);
11130 if (wire_type == (v & 0xff)) {
11131 d->pc = d->top->base + (v >> 16);
11132 return DECODE_OK;
11133 } else if (wire_type == ((v >> 8) & 0xff)) {
11134 bool found =
11135 upb_inttable_lookup(dispatch, fieldnum + UPB_MAX_FIELDNUMBER, &val);
Paul Yange0e54662016-09-15 11:09:01 -070011136 UPB_ASSERT(found);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011137 d->pc = d->top->base + upb_value_getuint64(val);
11138 return DECODE_OK;
11139 }
11140 }
11141
11142 /* We have some unknown fields (or ENDGROUP) to parse. The DISPATCH or TAG
11143 * bytecode that triggered this is preceded by a CHECKDELIM bytecode which
11144 * we need to back up to, so that when we're done skipping unknown data we
11145 * can re-check the delimited end. */
11146 d->last--; /* Necessary if we get suspended */
11147 d->pc = d->last;
Paul Yange0e54662016-09-15 11:09:01 -070011148 UPB_ASSERT(getop(*d->last) == OP_CHECKDELIM);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011149
11150 /* Unknown field or ENDGROUP. */
11151 retval = upb_pbdecoder_skipunknown(d, fieldnum, wire_type);
11152
11153 CHECK_RETURN(retval);
11154
11155 if (retval == DECODE_ENDGROUP) {
11156 goto_endmsg(d);
11157 return DECODE_OK;
11158 }
11159
11160 return DECODE_OK;
11161}
11162
11163/* Callers know that the stack is more than one deep because the opcodes that
11164 * call this only occur after PUSH operations. */
11165upb_pbdecoder_frame *outer_frame(upb_pbdecoder *d) {
Paul Yange0e54662016-09-15 11:09:01 -070011166 UPB_ASSERT(d->top != d->stack);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011167 return d->top - 1;
11168}
11169
11170
11171/* The main decoding loop *****************************************************/
11172
11173/* The main decoder VM function. Uses traditional bytecode dispatch loop with a
11174 * switch() statement. */
11175size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group,
11176 const upb_bufhandle* handle) {
11177
11178#define VMCASE(op, code) \
11179 case op: { code; if (consumes_input(op)) checkpoint(d); break; }
11180#define PRIMITIVE_OP(type, wt, name, convfunc, ctype) \
11181 VMCASE(OP_PARSE_ ## type, { \
11182 ctype val; \
11183 CHECK_RETURN(decode_ ## wt(d, &val)); \
11184 upb_sink_put ## name(&d->top->sink, arg, (convfunc)(val)); \
11185 })
11186
11187 while(1) {
11188 int32_t instruction;
11189 opcode op;
11190 uint32_t arg;
11191 int32_t longofs;
11192
11193 d->last = d->pc;
11194 instruction = *d->pc++;
11195 op = getop(instruction);
11196 arg = instruction >> 8;
11197 longofs = arg;
Paul Yange0e54662016-09-15 11:09:01 -070011198 UPB_ASSERT(d->ptr != d->residual_end);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011199 UPB_UNUSED(group);
11200#ifdef UPB_DUMP_BYTECODE
11201 fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d "
11202 "%x %s (%d)\n",
11203 (int)offset(d),
11204 (int)(d->ptr - d->buf),
11205 (int)(d->data_end - d->ptr),
11206 (int)(d->end - d->ptr),
11207 (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)),
11208 (int)(d->pc - 1 - group->bytecode),
11209 upb_pbdecoder_getopname(op),
11210 arg);
11211#endif
11212 switch (op) {
11213 /* Technically, we are losing data if we see a 32-bit varint that is not
11214 * properly sign-extended. We could detect this and error about the data
11215 * loss, but proto2 does not do this, so we pass. */
11216 PRIMITIVE_OP(INT32, varint, int32, int32_t, uint64_t)
11217 PRIMITIVE_OP(INT64, varint, int64, int64_t, uint64_t)
11218 PRIMITIVE_OP(UINT32, varint, uint32, uint32_t, uint64_t)
11219 PRIMITIVE_OP(UINT64, varint, uint64, uint64_t, uint64_t)
11220 PRIMITIVE_OP(FIXED32, fixed32, uint32, uint32_t, uint32_t)
11221 PRIMITIVE_OP(FIXED64, fixed64, uint64, uint64_t, uint64_t)
11222 PRIMITIVE_OP(SFIXED32, fixed32, int32, int32_t, uint32_t)
11223 PRIMITIVE_OP(SFIXED64, fixed64, int64, int64_t, uint64_t)
11224 PRIMITIVE_OP(BOOL, varint, bool, bool, uint64_t)
11225 PRIMITIVE_OP(DOUBLE, fixed64, double, as_double, uint64_t)
11226 PRIMITIVE_OP(FLOAT, fixed32, float, as_float, uint32_t)
11227 PRIMITIVE_OP(SINT32, varint, int32, upb_zzdec_32, uint64_t)
11228 PRIMITIVE_OP(SINT64, varint, int64, upb_zzdec_64, uint64_t)
11229
11230 VMCASE(OP_SETDISPATCH,
11231 d->top->base = d->pc - 1;
11232 memcpy(&d->top->dispatch, d->pc, sizeof(void*));
11233 d->pc += sizeof(void*) / sizeof(uint32_t);
11234 )
11235 VMCASE(OP_STARTMSG,
11236 CHECK_SUSPEND(upb_sink_startmsg(&d->top->sink));
11237 )
11238 VMCASE(OP_ENDMSG,
11239 CHECK_SUSPEND(upb_sink_endmsg(&d->top->sink, d->status));
11240 )
11241 VMCASE(OP_STARTSEQ,
11242 upb_pbdecoder_frame *outer = outer_frame(d);
11243 CHECK_SUSPEND(upb_sink_startseq(&outer->sink, arg, &d->top->sink));
11244 )
11245 VMCASE(OP_ENDSEQ,
11246 CHECK_SUSPEND(upb_sink_endseq(&d->top->sink, arg));
11247 )
11248 VMCASE(OP_STARTSUBMSG,
11249 upb_pbdecoder_frame *outer = outer_frame(d);
11250 CHECK_SUSPEND(upb_sink_startsubmsg(&outer->sink, arg, &d->top->sink));
11251 )
11252 VMCASE(OP_ENDSUBMSG,
11253 CHECK_SUSPEND(upb_sink_endsubmsg(&d->top->sink, arg));
11254 )
11255 VMCASE(OP_STARTSTR,
11256 uint32_t len = delim_remaining(d);
11257 upb_pbdecoder_frame *outer = outer_frame(d);
11258 CHECK_SUSPEND(upb_sink_startstr(&outer->sink, arg, len, &d->top->sink));
11259 if (len == 0) {
11260 d->pc++; /* Skip OP_STRING. */
11261 }
11262 )
11263 VMCASE(OP_STRING,
11264 uint32_t len = curbufleft(d);
11265 size_t n = upb_sink_putstring(&d->top->sink, arg, d->ptr, len, handle);
11266 if (n > len) {
11267 if (n > delim_remaining(d)) {
11268 seterr(d, "Tried to skip past end of string.");
11269 return upb_pbdecoder_suspend(d);
11270 } else {
11271 int32_t ret = skip(d, n);
11272 /* This shouldn't return DECODE_OK, because n > len. */
Paul Yange0e54662016-09-15 11:09:01 -070011273 UPB_ASSERT(ret >= 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011274 return ret;
11275 }
11276 }
11277 advance(d, n);
11278 if (n < len || d->delim_end == NULL) {
11279 /* We aren't finished with this string yet. */
11280 d->pc--; /* Repeat OP_STRING. */
11281 if (n > 0) checkpoint(d);
11282 return upb_pbdecoder_suspend(d);
11283 }
11284 )
11285 VMCASE(OP_ENDSTR,
11286 CHECK_SUSPEND(upb_sink_endstr(&d->top->sink, arg));
11287 )
11288 VMCASE(OP_PUSHTAGDELIM,
11289 CHECK_SUSPEND(pushtagdelim(d, arg));
11290 )
11291 VMCASE(OP_SETBIGGROUPNUM,
11292 d->top->groupnum = *d->pc++;
11293 )
11294 VMCASE(OP_POP,
Paul Yange0e54662016-09-15 11:09:01 -070011295 UPB_ASSERT(d->top > d->stack);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011296 decoder_pop(d);
11297 )
11298 VMCASE(OP_PUSHLENDELIM,
11299 uint32_t len;
11300 CHECK_RETURN(decode_v32(d, &len));
11301 CHECK_SUSPEND(decoder_push(d, offset(d) + len));
11302 set_delim_end(d);
11303 )
11304 VMCASE(OP_SETDELIM,
11305 set_delim_end(d);
11306 )
11307 VMCASE(OP_CHECKDELIM,
11308 /* We are guaranteed of this assert because we never allow ourselves to
11309 * consume bytes beyond data_end, which covers delim_end when non-NULL.
11310 */
Paul Yange0e54662016-09-15 11:09:01 -070011311 UPB_ASSERT(!(d->delim_end && d->ptr > d->delim_end));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011312 if (d->ptr == d->delim_end)
11313 d->pc += longofs;
11314 )
11315 VMCASE(OP_CALL,
11316 d->callstack[d->call_len++] = d->pc;
11317 d->pc += longofs;
11318 )
11319 VMCASE(OP_RET,
Paul Yange0e54662016-09-15 11:09:01 -070011320 UPB_ASSERT(d->call_len > 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011321 d->pc = d->callstack[--d->call_len];
11322 )
11323 VMCASE(OP_BRANCH,
11324 d->pc += longofs;
11325 )
11326 VMCASE(OP_TAG1,
11327 uint8_t expected;
11328 CHECK_SUSPEND(curbufleft(d) > 0);
11329 expected = (arg >> 8) & 0xff;
11330 if (*d->ptr == expected) {
11331 advance(d, 1);
11332 } else {
11333 int8_t shortofs;
11334 badtag:
11335 shortofs = arg;
11336 if (shortofs == LABEL_DISPATCH) {
11337 CHECK_RETURN(dispatch(d));
11338 } else {
11339 d->pc += shortofs;
11340 break; /* Avoid checkpoint(). */
11341 }
11342 }
11343 )
11344 VMCASE(OP_TAG2,
11345 uint16_t expected;
11346 CHECK_SUSPEND(curbufleft(d) > 0);
11347 expected = (arg >> 8) & 0xffff;
11348 if (curbufleft(d) >= 2) {
11349 uint16_t actual;
11350 memcpy(&actual, d->ptr, 2);
11351 if (expected == actual) {
11352 advance(d, 2);
11353 } else {
11354 goto badtag;
11355 }
11356 } else {
11357 int32_t result = upb_pbdecoder_checktag_slow(d, expected);
11358 if (result == DECODE_MISMATCH) goto badtag;
11359 if (result >= 0) return result;
11360 }
11361 )
11362 VMCASE(OP_TAGN, {
11363 uint64_t expected;
11364 int32_t result;
11365 memcpy(&expected, d->pc, 8);
11366 d->pc += 2;
11367 result = upb_pbdecoder_checktag_slow(d, expected);
11368 if (result == DECODE_MISMATCH) goto badtag;
11369 if (result >= 0) return result;
11370 })
11371 VMCASE(OP_DISPATCH, {
11372 CHECK_RETURN(dispatch(d));
11373 })
11374 VMCASE(OP_HALT, {
11375 return d->size_param;
11376 })
11377 }
11378 }
11379}
11380
11381
11382/* BytesHandler handlers ******************************************************/
11383
11384void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) {
11385 upb_pbdecoder *d = closure;
11386 UPB_UNUSED(size_hint);
11387 d->top->end_ofs = UINT64_MAX;
11388 d->bufstart_ofs = 0;
11389 d->call_len = 1;
11390 d->callstack[0] = &halt;
11391 d->pc = pc;
11392 d->skip = 0;
11393 return d;
11394}
11395
11396void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint) {
11397 upb_pbdecoder *d = closure;
11398 UPB_UNUSED(hd);
11399 UPB_UNUSED(size_hint);
11400 d->top->end_ofs = UINT64_MAX;
11401 d->bufstart_ofs = 0;
11402 d->call_len = 0;
11403 d->skip = 0;
11404 return d;
11405}
11406
11407bool upb_pbdecoder_end(void *closure, const void *handler_data) {
11408 upb_pbdecoder *d = closure;
11409 const upb_pbdecodermethod *method = handler_data;
11410 uint64_t end;
11411 char dummy;
11412
11413 if (d->residual_end > d->residual) {
11414 seterr(d, "Unexpected EOF: decoder still has buffered unparsed data");
11415 return false;
11416 }
11417
11418 if (d->skip) {
11419 seterr(d, "Unexpected EOF inside skipped data");
11420 return false;
11421 }
11422
11423 if (d->top->end_ofs != UINT64_MAX) {
11424 seterr(d, "Unexpected EOF inside delimited string");
11425 return false;
11426 }
11427
11428 /* The user's end() call indicates that the message ends here. */
11429 end = offset(d);
11430 d->top->end_ofs = end;
11431
11432#ifdef UPB_USE_JIT_X64
11433 if (method->is_native_) {
11434 const mgroup *group = (const mgroup*)method->group;
11435 if (d->top != d->stack)
11436 d->stack->end_ofs = 0;
11437 group->jit_code(closure, method->code_base.ptr, &dummy, 0, NULL);
11438 } else
11439#endif
11440 {
11441 const uint32_t *p = d->pc;
11442 d->stack->end_ofs = end;
11443 /* Check the previous bytecode, but guard against beginning. */
11444 if (p != method->code_base.ptr) p--;
11445 if (getop(*p) == OP_CHECKDELIM) {
11446 /* Rewind from OP_TAG* to OP_CHECKDELIM. */
Paul Yange0e54662016-09-15 11:09:01 -070011447 UPB_ASSERT(getop(*d->pc) == OP_TAG1 ||
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011448 getop(*d->pc) == OP_TAG2 ||
11449 getop(*d->pc) == OP_TAGN ||
11450 getop(*d->pc) == OP_DISPATCH);
11451 d->pc = p;
11452 }
11453 upb_pbdecoder_decode(closure, handler_data, &dummy, 0, NULL);
11454 }
11455
11456 if (d->call_len != 0) {
11457 seterr(d, "Unexpected EOF inside submessage or group");
11458 return false;
11459 }
11460
11461 return true;
11462}
11463
11464size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf,
11465 size_t size, const upb_bufhandle *handle) {
11466 int32_t result = upb_pbdecoder_resume(decoder, NULL, buf, size, handle);
11467
11468 if (result == DECODE_ENDGROUP) goto_endmsg(decoder);
11469 CHECK_RETURN(result);
11470
11471 return run_decoder_vm(decoder, group, handle);
11472}
11473
11474
11475/* Public API *****************************************************************/
11476
11477void upb_pbdecoder_reset(upb_pbdecoder *d) {
11478 d->top = d->stack;
11479 d->top->groupnum = 0;
11480 d->ptr = d->residual;
11481 d->buf = d->residual;
11482 d->end = d->residual;
11483 d->residual_end = d->residual;
11484}
11485
11486upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m,
11487 upb_sink *sink) {
11488 const size_t default_max_nesting = 64;
11489#ifndef NDEBUG
11490 size_t size_before = upb_env_bytesallocated(e);
11491#endif
11492
11493 upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder));
11494 if (!d) return NULL;
11495
11496 d->method_ = m;
11497 d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting));
11498 d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting));
11499 if (!d->stack || !d->callstack) {
11500 return NULL;
11501 }
11502
11503 d->env = e;
11504 d->limit = d->stack + default_max_nesting - 1;
11505 d->stack_size = default_max_nesting;
Paul Yange0e54662016-09-15 11:09:01 -070011506 d->status = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011507
11508 upb_pbdecoder_reset(d);
11509 upb_bytessink_reset(&d->input_, &m->input_handler_, d);
11510
Paul Yange0e54662016-09-15 11:09:01 -070011511 UPB_ASSERT(sink);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011512 if (d->method_->dest_handlers_) {
11513 if (sink->handlers != d->method_->dest_handlers_)
11514 return NULL;
11515 }
11516 upb_sink_reset(&d->top->sink, sink->handlers, sink->closure);
11517
11518 /* If this fails, increase the value in decoder.h. */
Paul Yange0e54662016-09-15 11:09:01 -070011519 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
11520 UPB_PB_DECODER_SIZE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011521 return d;
11522}
11523
11524uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
11525 return offset(d);
11526}
11527
11528const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
11529 return d->method_;
11530}
11531
11532upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d) {
11533 return &d->input_;
11534}
11535
11536size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) {
11537 return d->stack_size;
11538}
11539
11540bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
Paul Yange0e54662016-09-15 11:09:01 -070011541 UPB_ASSERT(d->top >= d->stack);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011542
11543 if (max < (size_t)(d->top - d->stack)) {
11544 /* Can't set a limit smaller than what we are currently at. */
11545 return false;
11546 }
11547
11548 if (max > d->stack_size) {
11549 /* Need to reallocate stack and callstack to accommodate. */
11550 size_t old_size = stacksize(d, d->stack_size);
11551 size_t new_size = stacksize(d, max);
11552 void *p = upb_env_realloc(d->env, d->stack, old_size, new_size);
11553 if (!p) {
11554 return false;
11555 }
11556 d->stack = p;
11557
11558 old_size = callstacksize(d, d->stack_size);
11559 new_size = callstacksize(d, max);
11560 p = upb_env_realloc(d->env, d->callstack, old_size, new_size);
11561 if (!p) {
11562 return false;
11563 }
11564 d->callstack = p;
11565
11566 d->stack_size = max;
11567 }
11568
11569 d->limit = d->stack + max - 1;
11570 return true;
11571}
11572/*
11573** upb::Encoder
11574**
11575** Since we are implementing pure handlers (ie. without any out-of-band access
11576** to pre-computed lengths), we have to buffer all submessages before we can
11577** emit even their first byte.
11578**
11579** Not knowing the size of submessages also means we can't write a perfect
11580** zero-copy implementation, even with buffering. Lengths are stored as
11581** varints, which means that we don't know how many bytes to reserve for the
11582** length until we know what the length is.
11583**
11584** This leaves us with three main choices:
11585**
11586** 1. buffer all submessage data in a temporary buffer, then copy it exactly
11587** once into the output buffer.
11588**
11589** 2. attempt to buffer data directly into the output buffer, estimating how
11590** many bytes each length will take. When our guesses are wrong, use
11591** memmove() to grow or shrink the allotted space.
11592**
11593** 3. buffer directly into the output buffer, allocating a max length
11594** ahead-of-time for each submessage length. If we overallocated, we waste
11595** space, but no memcpy() or memmove() is required. This approach requires
11596** defining a maximum size for submessages and rejecting submessages that
11597** exceed that size.
11598**
11599** (2) and (3) have the potential to have better performance, but they are more
11600** complicated and subtle to implement:
11601**
11602** (3) requires making an arbitrary choice of the maximum message size; it
11603** wastes space when submessages are shorter than this and fails
11604** completely when they are longer. This makes it more finicky and
11605** requires configuration based on the input. It also makes it impossible
11606** to perfectly match the output of reference encoders that always use the
11607** optimal amount of space for each length.
11608**
11609** (2) requires guessing the the size upfront, and if multiple lengths are
11610** guessed wrong the minimum required number of memmove() operations may
11611** be complicated to compute correctly. Implemented properly, it may have
11612** a useful amortized or average cost, but more investigation is required
11613** to determine this and what the optimal algorithm is to achieve it.
11614**
11615** (1) makes you always pay for exactly one copy, but its implementation is
11616** the simplest and its performance is predictable.
11617**
11618** So for now, we implement (1) only. If we wish to optimize later, we should
11619** be able to do it without affecting users.
11620**
11621** The strategy is to buffer the segments of data that do *not* depend on
11622** unknown lengths in one buffer, and keep a separate buffer of segment pointers
11623** and lengths. When the top-level submessage ends, we can go beginning to end,
11624** alternating the writing of lengths with memcpy() of the rest of the data.
11625** At the top level though, no buffering is required.
11626*/
11627
11628
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011629
11630/* The output buffer is divided into segments; a segment is a string of data
11631 * that is "ready to go" -- it does not need any varint lengths inserted into
11632 * the middle. The seams between segments are where varints will be inserted
11633 * once they are known.
11634 *
11635 * We also use the concept of a "run", which is a range of encoded bytes that
11636 * occur at a single submessage level. Every segment contains one or more runs.
11637 *
11638 * A segment can span messages. Consider:
11639 *
11640 * .--Submessage lengths---------.
11641 * | | |
11642 * | V V
11643 * V | |--------------- | |-----------------
11644 * Submessages: | |-----------------------------------------------
11645 * Top-level msg: ------------------------------------------------------------
11646 *
11647 * Segments: ----- ------------------- -----------------
11648 * Runs: *---- *--------------*--- *----------------
11649 * (* marks the start)
11650 *
11651 * Note that the top-level menssage is not in any segment because it does not
11652 * have any length preceding it.
11653 *
11654 * A segment is only interrupted when another length needs to be inserted. So
11655 * observe how the second segment spans both the inner submessage and part of
11656 * the next enclosing message. */
11657typedef struct {
11658 uint32_t msglen; /* The length to varint-encode before this segment. */
11659 uint32_t seglen; /* Length of the segment. */
11660} upb_pb_encoder_segment;
11661
11662struct upb_pb_encoder {
11663 upb_env *env;
11664
11665 /* Our input and output. */
11666 upb_sink input_;
11667 upb_bytessink *output_;
11668
11669 /* The "subclosure" -- used as the inner closure as part of the bytessink
11670 * protocol. */
11671 void *subc;
11672
11673 /* The output buffer and limit, and our current write position. "buf"
11674 * initially points to "initbuf", but is dynamically allocated if we need to
11675 * grow beyond the initial size. */
11676 char *buf, *ptr, *limit;
11677
11678 /* The beginning of the current run, or undefined if we are at the top
11679 * level. */
11680 char *runbegin;
11681
11682 /* The list of segments we are accumulating. */
11683 upb_pb_encoder_segment *segbuf, *segptr, *seglimit;
11684
11685 /* The stack of enclosing submessages. Each entry in the stack points to the
11686 * segment where this submessage's length is being accumulated. */
11687 int *stack, *top, *stacklimit;
11688
11689 /* Depth of startmsg/endmsg calls. */
11690 int depth;
11691};
11692
11693/* low-level buffering ********************************************************/
11694
11695/* Low-level functions for interacting with the output buffer. */
11696
11697/* TODO(haberman): handle pushback */
11698static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) {
11699 size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL);
Paul Yange0e54662016-09-15 11:09:01 -070011700 UPB_ASSERT(n == len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011701}
11702
11703static upb_pb_encoder_segment *top(upb_pb_encoder *e) {
11704 return &e->segbuf[*e->top];
11705}
11706
11707/* Call to ensure that at least "bytes" bytes are available for writing at
11708 * e->ptr. Returns false if the bytes could not be allocated. */
11709static bool reserve(upb_pb_encoder *e, size_t bytes) {
11710 if ((size_t)(e->limit - e->ptr) < bytes) {
11711 /* Grow buffer. */
11712 char *new_buf;
11713 size_t needed = bytes + (e->ptr - e->buf);
11714 size_t old_size = e->limit - e->buf;
11715
11716 size_t new_size = old_size;
11717
11718 while (new_size < needed) {
11719 new_size *= 2;
11720 }
11721
11722 new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
11723
11724 if (new_buf == NULL) {
11725 return false;
11726 }
11727
11728 e->ptr = new_buf + (e->ptr - e->buf);
11729 e->runbegin = new_buf + (e->runbegin - e->buf);
11730 e->limit = new_buf + new_size;
11731 e->buf = new_buf;
11732 }
11733
11734 return true;
11735}
11736
11737/* Call when "bytes" bytes have been writte at e->ptr. The caller *must* have
11738 * previously called reserve() with at least this many bytes. */
11739static void encoder_advance(upb_pb_encoder *e, size_t bytes) {
Paul Yange0e54662016-09-15 11:09:01 -070011740 UPB_ASSERT((size_t)(e->limit - e->ptr) >= bytes);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011741 e->ptr += bytes;
11742}
11743
11744/* Call when all of the bytes for a handler have been written. Flushes the
11745 * bytes if possible and necessary, returning false if this failed. */
11746static bool commit(upb_pb_encoder *e) {
11747 if (!e->top) {
11748 /* We aren't inside a delimited region. Flush our accumulated bytes to
11749 * the output.
11750 *
11751 * TODO(haberman): in the future we may want to delay flushing for
11752 * efficiency reasons. */
11753 putbuf(e, e->buf, e->ptr - e->buf);
11754 e->ptr = e->buf;
11755 }
11756
11757 return true;
11758}
11759
11760/* Writes the given bytes to the buffer, handling reserve/advance. */
11761static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) {
11762 if (!reserve(e, len)) {
11763 return false;
11764 }
11765
11766 memcpy(e->ptr, data, len);
11767 encoder_advance(e, len);
11768 return true;
11769}
11770
11771/* Finish the current run by adding the run totals to the segment and message
11772 * length. */
11773static void accumulate(upb_pb_encoder *e) {
11774 size_t run_len;
Paul Yange0e54662016-09-15 11:09:01 -070011775 UPB_ASSERT(e->ptr >= e->runbegin);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011776 run_len = e->ptr - e->runbegin;
11777 e->segptr->seglen += run_len;
11778 top(e)->msglen += run_len;
11779 e->runbegin = e->ptr;
11780}
11781
11782/* Call to indicate the start of delimited region for which the full length is
11783 * not yet known. All data will be buffered until the length is known.
11784 * Delimited regions may be nested; their lengths will all be tracked properly. */
11785static bool start_delim(upb_pb_encoder *e) {
11786 if (e->top) {
11787 /* We are already buffering, advance to the next segment and push it on the
11788 * stack. */
11789 accumulate(e);
11790
11791 if (++e->top == e->stacklimit) {
11792 /* TODO(haberman): grow stack? */
11793 return false;
11794 }
11795
11796 if (++e->segptr == e->seglimit) {
11797 /* Grow segment buffer. */
11798 size_t old_size =
11799 (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
11800 size_t new_size = old_size * 2;
11801 upb_pb_encoder_segment *new_buf =
11802 upb_env_realloc(e->env, e->segbuf, old_size, new_size);
11803
11804 if (new_buf == NULL) {
11805 return false;
11806 }
11807
11808 e->segptr = new_buf + (e->segptr - e->segbuf);
11809 e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment));
11810 e->segbuf = new_buf;
11811 }
11812 } else {
11813 /* We were previously at the top level, start buffering. */
11814 e->segptr = e->segbuf;
11815 e->top = e->stack;
11816 e->runbegin = e->ptr;
11817 }
11818
11819 *e->top = e->segptr - e->segbuf;
11820 e->segptr->seglen = 0;
11821 e->segptr->msglen = 0;
11822
11823 return true;
11824}
11825
11826/* Call to indicate the end of a delimited region. We now know the length of
11827 * the delimited region. If we are not nested inside any other delimited
11828 * regions, we can now emit all of the buffered data we accumulated. */
11829static bool end_delim(upb_pb_encoder *e) {
11830 size_t msglen;
11831 accumulate(e);
11832 msglen = top(e)->msglen;
11833
11834 if (e->top == e->stack) {
11835 /* All lengths are now available, emit all buffered data. */
11836 char buf[UPB_PB_VARINT_MAX_LEN];
11837 upb_pb_encoder_segment *s;
11838 const char *ptr = e->buf;
11839 for (s = e->segbuf; s <= e->segptr; s++) {
11840 size_t lenbytes = upb_vencode64(s->msglen, buf);
11841 putbuf(e, buf, lenbytes);
11842 putbuf(e, ptr, s->seglen);
11843 ptr += s->seglen;
11844 }
11845
11846 e->ptr = e->buf;
11847 e->top = NULL;
11848 } else {
11849 /* Need to keep buffering; propagate length info into enclosing
11850 * submessages. */
11851 --e->top;
11852 top(e)->msglen += msglen + upb_varint_size(msglen);
11853 }
11854
11855 return true;
11856}
11857
11858
11859/* tag_t **********************************************************************/
11860
11861/* A precomputed (pre-encoded) tag and length. */
11862
11863typedef struct {
11864 uint8_t bytes;
11865 char tag[7];
11866} tag_t;
11867
11868/* Allocates a new tag for this field, and sets it in these handlerattr. */
11869static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
11870 upb_handlerattr *attr) {
11871 uint32_t n = upb_fielddef_number(f);
11872
Paul Yange0e54662016-09-15 11:09:01 -070011873 tag_t *tag = upb_gmalloc(sizeof(tag_t));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011874 tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
11875
11876 upb_handlerattr_init(attr);
11877 upb_handlerattr_sethandlerdata(attr, tag);
Paul Yange0e54662016-09-15 11:09:01 -070011878 upb_handlers_addcleanup(h, tag, upb_gfree);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011879}
11880
11881static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
11882 return encode_bytes(e, tag->tag, tag->bytes);
11883}
11884
11885
11886/* encoding of wire types *****************************************************/
11887
11888static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) {
11889 /* TODO(haberman): byte-swap for big endian. */
11890 return encode_bytes(e, &val, sizeof(uint64_t));
11891}
11892
11893static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) {
11894 /* TODO(haberman): byte-swap for big endian. */
11895 return encode_bytes(e, &val, sizeof(uint32_t));
11896}
11897
11898static bool encode_varint(upb_pb_encoder *e, uint64_t val) {
11899 if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) {
11900 return false;
11901 }
11902
11903 encoder_advance(e, upb_vencode64(val, e->ptr));
11904 return true;
11905}
11906
11907static uint64_t dbl2uint64(double d) {
11908 uint64_t ret;
11909 memcpy(&ret, &d, sizeof(uint64_t));
11910 return ret;
11911}
11912
11913static uint32_t flt2uint32(float d) {
11914 uint32_t ret;
11915 memcpy(&ret, &d, sizeof(uint32_t));
11916 return ret;
11917}
11918
11919
11920/* encoding of proto types ****************************************************/
11921
11922static bool startmsg(void *c, const void *hd) {
11923 upb_pb_encoder *e = c;
11924 UPB_UNUSED(hd);
11925 if (e->depth++ == 0) {
11926 upb_bytessink_start(e->output_, 0, &e->subc);
11927 }
11928 return true;
11929}
11930
11931static bool endmsg(void *c, const void *hd, upb_status *status) {
11932 upb_pb_encoder *e = c;
11933 UPB_UNUSED(hd);
11934 UPB_UNUSED(status);
11935 if (--e->depth == 0) {
11936 upb_bytessink_end(e->output_);
11937 }
11938 return true;
11939}
11940
11941static void *encode_startdelimfield(void *c, const void *hd) {
11942 bool ok = encode_tag(c, hd) && commit(c) && start_delim(c);
11943 return ok ? c : UPB_BREAK;
11944}
11945
Paul Yang60327462017-10-09 12:39:13 -070011946static bool encode_unknown(void *c, const void *hd, const char *buf,
11947 size_t len) {
11948 UPB_UNUSED(hd);
11949 return encode_bytes(c, buf, len) && commit(c);
11950}
11951
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011952static bool encode_enddelimfield(void *c, const void *hd) {
11953 UPB_UNUSED(hd);
11954 return end_delim(c);
11955}
11956
11957static void *encode_startgroup(void *c, const void *hd) {
11958 return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK;
11959}
11960
11961static bool encode_endgroup(void *c, const void *hd) {
11962 return encode_tag(c, hd) && commit(c);
11963}
11964
11965static void *encode_startstr(void *c, const void *hd, size_t size_hint) {
11966 UPB_UNUSED(size_hint);
11967 return encode_startdelimfield(c, hd);
11968}
11969
11970static size_t encode_strbuf(void *c, const void *hd, const char *buf,
11971 size_t len, const upb_bufhandle *h) {
11972 UPB_UNUSED(hd);
11973 UPB_UNUSED(h);
11974 return encode_bytes(c, buf, len) ? len : 0;
11975}
11976
11977#define T(type, ctype, convert, encode) \
11978 static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \
11979 return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e); \
11980 } \
11981 static bool encode_packed_##type(void *e, const void *hd, ctype val) { \
11982 UPB_UNUSED(hd); \
11983 return encode(e, (convert)(val)); \
11984 }
11985
11986T(double, double, dbl2uint64, encode_fixed64)
11987T(float, float, flt2uint32, encode_fixed32)
11988T(int64, int64_t, uint64_t, encode_varint)
Paul Yangf23869c2017-02-07 21:33:28 -080011989T(int32, int32_t, int64_t, encode_varint)
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070011990T(fixed64, uint64_t, uint64_t, encode_fixed64)
11991T(fixed32, uint32_t, uint32_t, encode_fixed32)
11992T(bool, bool, bool, encode_varint)
11993T(uint32, uint32_t, uint32_t, encode_varint)
11994T(uint64, uint64_t, uint64_t, encode_varint)
11995T(enum, int32_t, uint32_t, encode_varint)
11996T(sfixed32, int32_t, uint32_t, encode_fixed32)
11997T(sfixed64, int64_t, uint64_t, encode_fixed64)
11998T(sint32, int32_t, upb_zzenc_32, encode_varint)
11999T(sint64, int64_t, upb_zzenc_64, encode_varint)
12000
12001#undef T
12002
12003
12004/* code to build the handlers *************************************************/
12005
12006static void newhandlers_callback(const void *closure, upb_handlers *h) {
12007 const upb_msgdef *m;
12008 upb_msg_field_iter i;
12009
12010 UPB_UNUSED(closure);
12011
12012 upb_handlers_setstartmsg(h, startmsg, NULL);
12013 upb_handlers_setendmsg(h, endmsg, NULL);
Paul Yang60327462017-10-09 12:39:13 -070012014 upb_handlers_setunknown(h, encode_unknown, NULL);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012015
12016 m = upb_handlers_msgdef(h);
12017 for(upb_msg_field_begin(&i, m);
12018 !upb_msg_field_done(&i);
12019 upb_msg_field_next(&i)) {
12020 const upb_fielddef *f = upb_msg_iter_field(&i);
12021 bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
12022 upb_fielddef_packed(f);
12023 upb_handlerattr attr;
12024 upb_wiretype_t wt =
12025 packed ? UPB_WIRE_TYPE_DELIMITED
12026 : upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
12027
12028 /* Pre-encode the tag for this field. */
12029 new_tag(h, f, wt, &attr);
12030
12031 if (packed) {
12032 upb_handlers_setstartseq(h, f, encode_startdelimfield, &attr);
12033 upb_handlers_setendseq(h, f, encode_enddelimfield, &attr);
12034 }
12035
12036#define T(upper, lower, upbtype) \
12037 case UPB_DESCRIPTOR_TYPE_##upper: \
12038 if (packed) { \
12039 upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \
12040 } else { \
12041 upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \
12042 } \
12043 break;
12044
12045 switch (upb_fielddef_descriptortype(f)) {
12046 T(DOUBLE, double, double);
12047 T(FLOAT, float, float);
12048 T(INT64, int64, int64);
12049 T(INT32, int32, int32);
12050 T(FIXED64, fixed64, uint64);
12051 T(FIXED32, fixed32, uint32);
12052 T(BOOL, bool, bool);
12053 T(UINT32, uint32, uint32);
12054 T(UINT64, uint64, uint64);
12055 T(ENUM, enum, int32);
12056 T(SFIXED32, sfixed32, int32);
12057 T(SFIXED64, sfixed64, int64);
12058 T(SINT32, sint32, int32);
12059 T(SINT64, sint64, int64);
12060 case UPB_DESCRIPTOR_TYPE_STRING:
12061 case UPB_DESCRIPTOR_TYPE_BYTES:
12062 upb_handlers_setstartstr(h, f, encode_startstr, &attr);
12063 upb_handlers_setendstr(h, f, encode_enddelimfield, &attr);
12064 upb_handlers_setstring(h, f, encode_strbuf, &attr);
12065 break;
12066 case UPB_DESCRIPTOR_TYPE_MESSAGE:
12067 upb_handlers_setstartsubmsg(h, f, encode_startdelimfield, &attr);
12068 upb_handlers_setendsubmsg(h, f, encode_enddelimfield, &attr);
12069 break;
12070 case UPB_DESCRIPTOR_TYPE_GROUP: {
12071 /* Endgroup takes a different tag (wire_type = END_GROUP). */
12072 upb_handlerattr attr2;
12073 new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2);
12074
12075 upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr);
12076 upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2);
12077
12078 upb_handlerattr_uninit(&attr2);
12079 break;
12080 }
12081 }
12082
12083#undef T
12084
12085 upb_handlerattr_uninit(&attr);
12086 }
12087}
12088
12089void upb_pb_encoder_reset(upb_pb_encoder *e) {
12090 e->segptr = NULL;
12091 e->top = NULL;
12092 e->depth = 0;
12093}
12094
12095
12096/* public API *****************************************************************/
12097
12098const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
12099 const void *owner) {
12100 return upb_handlers_newfrozen(m, owner, newhandlers_callback, NULL);
12101}
12102
12103upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
12104 upb_bytessink *output) {
12105 const size_t initial_bufsize = 256;
12106 const size_t initial_segbufsize = 16;
12107 /* TODO(haberman): make this configurable. */
12108 const size_t stack_size = 64;
12109#ifndef NDEBUG
12110 const size_t size_before = upb_env_bytesallocated(env);
12111#endif
12112
12113 upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder));
12114 if (!e) return NULL;
12115
12116 e->buf = upb_env_malloc(env, initial_bufsize);
12117 e->segbuf = upb_env_malloc(env, initial_segbufsize * sizeof(*e->segbuf));
12118 e->stack = upb_env_malloc(env, stack_size * sizeof(*e->stack));
12119
12120 if (!e->buf || !e->segbuf || !e->stack) {
12121 return NULL;
12122 }
12123
12124 e->limit = e->buf + initial_bufsize;
12125 e->seglimit = e->segbuf + initial_segbufsize;
12126 e->stacklimit = e->stack + stack_size;
12127
12128 upb_pb_encoder_reset(e);
12129 upb_sink_reset(&e->input_, h, e);
12130
12131 e->env = env;
12132 e->output_ = output;
12133 e->subc = output->closure;
12134 e->ptr = e->buf;
12135
12136 /* If this fails, increase the value in encoder.h. */
Paul Yange0e54662016-09-15 11:09:01 -070012137 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
12138 UPB_PB_ENCODER_SIZE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012139 return e;
12140}
12141
12142upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
12143
12144
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012145
Paul Yange0e54662016-09-15 11:09:01 -070012146upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
12147 upb_status *status) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012148 /* Create handlers. */
12149 const upb_pbdecodermethod *decoder_m;
12150 const upb_handlers *reader_h = upb_descreader_newhandlers(&reader_h);
12151 upb_env env;
12152 upb_pbdecodermethodopts opts;
12153 upb_pbdecoder *decoder;
12154 upb_descreader *reader;
12155 bool ok;
Paul Yange0e54662016-09-15 11:09:01 -070012156 size_t i;
12157 upb_filedef **ret = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012158
12159 upb_pbdecodermethodopts_init(&opts, reader_h);
12160 decoder_m = upb_pbdecodermethod_new(&opts, &decoder_m);
12161
12162 upb_env_init(&env);
12163 upb_env_reporterrorsto(&env, status);
12164
12165 reader = upb_descreader_create(&env, reader_h);
12166 decoder = upb_pbdecoder_create(&env, decoder_m, upb_descreader_input(reader));
12167
12168 /* Push input data. */
Paul Yange0e54662016-09-15 11:09:01 -070012169 ok = upb_bufsrc_putbuf(buf, n, upb_pbdecoder_input(decoder));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012170
Paul Yange0e54662016-09-15 11:09:01 -070012171 if (!ok) {
12172 goto cleanup;
12173 }
12174
12175 ret = upb_gmalloc(sizeof (*ret) * (upb_descreader_filecount(reader) + 1));
12176
12177 if (!ret) {
12178 goto cleanup;
12179 }
12180
12181 for (i = 0; i < upb_descreader_filecount(reader); i++) {
12182 ret[i] = upb_descreader_file(reader, i);
12183 upb_filedef_ref(ret[i], owner);
12184 }
12185
12186 ret[i] = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012187
12188cleanup:
12189 upb_env_uninit(&env);
12190 upb_handlers_unref(reader_h, &reader_h);
12191 upb_pbdecodermethod_unref(decoder_m, &decoder_m);
12192 return ret;
12193}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012194/*
12195 * upb::pb::TextPrinter
12196 *
12197 * OPT: This is not optimized at all. It uses printf() which parses the format
12198 * string every time, and it allocates memory for every put.
12199 */
12200
12201
12202#include <ctype.h>
12203#include <float.h>
12204#include <inttypes.h>
12205#include <stdarg.h>
12206#include <stdio.h>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012207#include <string.h>
12208
12209
12210struct upb_textprinter {
12211 upb_sink input_;
12212 upb_bytessink *output_;
12213 int indent_depth_;
12214 bool single_line_;
12215 void *subc;
12216};
12217
12218#define CHECK(x) if ((x) < 0) goto err;
12219
12220static const char *shortname(const char *longname) {
12221 const char *last = strrchr(longname, '.');
12222 return last ? last + 1 : longname;
12223}
12224
12225static int indent(upb_textprinter *p) {
12226 int i;
12227 if (!p->single_line_)
12228 for (i = 0; i < p->indent_depth_; i++)
12229 upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL);
12230 return 0;
12231}
12232
12233static int endfield(upb_textprinter *p) {
12234 const char ch = (p->single_line_ ? ' ' : '\n');
12235 upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL);
12236 return 0;
12237}
12238
12239static int putescaped(upb_textprinter *p, const char *buf, size_t len,
12240 bool preserve_utf8) {
12241 /* Based on CEscapeInternal() from Google's protobuf release. */
12242 char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf);
12243 const char *end = buf + len;
12244
12245 /* I think hex is prettier and more useful, but proto2 uses octal; should
12246 * investigate whether it can parse hex also. */
12247 const bool use_hex = false;
12248 bool last_hex_escape = false; /* true if last output char was \xNN */
12249
12250 for (; buf < end; buf++) {
12251 bool is_hex_escape;
12252
12253 if (dstend - dst < 4) {
12254 upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
12255 dst = dstbuf;
12256 }
12257
12258 is_hex_escape = false;
12259 switch (*buf) {
12260 case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break;
12261 case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break;
12262 case '\t': *(dst++) = '\\'; *(dst++) = 't'; break;
12263 case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break;
12264 case '\'': *(dst++) = '\\'; *(dst++) = '\''; break;
12265 case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break;
12266 default:
12267 /* Note that if we emit \xNN and the buf character after that is a hex
12268 * digit then that digit must be escaped too to prevent it being
12269 * interpreted as part of the character code by C. */
12270 if ((!preserve_utf8 || (uint8_t)*buf < 0x80) &&
12271 (!isprint(*buf) || (last_hex_escape && isxdigit(*buf)))) {
12272 sprintf(dst, (use_hex ? "\\x%02x" : "\\%03o"), (uint8_t)*buf);
12273 is_hex_escape = use_hex;
12274 dst += 4;
12275 } else {
12276 *(dst++) = *buf; break;
12277 }
12278 }
12279 last_hex_escape = is_hex_escape;
12280 }
12281 /* Flush remaining data. */
12282 upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
12283 return 0;
12284}
12285
12286bool putf(upb_textprinter *p, const char *fmt, ...) {
12287 va_list args;
12288 va_list args_copy;
12289 char *str;
12290 int written;
12291 int len;
12292 bool ok;
12293
12294 va_start(args, fmt);
12295
12296 /* Run once to get the length of the string. */
12297 _upb_va_copy(args_copy, args);
12298 len = _upb_vsnprintf(NULL, 0, fmt, args_copy);
12299 va_end(args_copy);
12300
12301 /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
Paul Yange0e54662016-09-15 11:09:01 -070012302 str = upb_gmalloc(len + 1);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012303 if (!str) return false;
12304 written = vsprintf(str, fmt, args);
12305 va_end(args);
Paul Yange0e54662016-09-15 11:09:01 -070012306 UPB_ASSERT(written == len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012307
12308 ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
Paul Yange0e54662016-09-15 11:09:01 -070012309 upb_gfree(str);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012310 return ok;
12311}
12312
12313
12314/* handlers *******************************************************************/
12315
12316static bool textprinter_startmsg(void *c, const void *hd) {
12317 upb_textprinter *p = c;
12318 UPB_UNUSED(hd);
12319 if (p->indent_depth_ == 0) {
12320 upb_bytessink_start(p->output_, 0, &p->subc);
12321 }
12322 return true;
12323}
12324
12325static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) {
12326 upb_textprinter *p = c;
12327 UPB_UNUSED(hd);
12328 UPB_UNUSED(s);
12329 if (p->indent_depth_ == 0) {
12330 upb_bytessink_end(p->output_);
12331 }
12332 return true;
12333}
12334
12335#define TYPE(name, ctype, fmt) \
12336 static bool textprinter_put ## name(void *closure, const void *handler_data, \
12337 ctype val) { \
12338 upb_textprinter *p = closure; \
12339 const upb_fielddef *f = handler_data; \
12340 CHECK(indent(p)); \
12341 putf(p, "%s: " fmt, upb_fielddef_name(f), val); \
12342 CHECK(endfield(p)); \
12343 return true; \
12344 err: \
12345 return false; \
12346}
12347
12348static bool textprinter_putbool(void *closure, const void *handler_data,
12349 bool val) {
12350 upb_textprinter *p = closure;
12351 const upb_fielddef *f = handler_data;
12352 CHECK(indent(p));
12353 putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false");
12354 CHECK(endfield(p));
12355 return true;
12356err:
12357 return false;
12358}
12359
12360#define STRINGIFY_HELPER(x) #x
12361#define STRINGIFY_MACROVAL(x) STRINGIFY_HELPER(x)
12362
12363TYPE(int32, int32_t, "%" PRId32)
12364TYPE(int64, int64_t, "%" PRId64)
12365TYPE(uint32, uint32_t, "%" PRIu32)
12366TYPE(uint64, uint64_t, "%" PRIu64)
12367TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g")
12368TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g")
12369
12370#undef TYPE
12371
12372/* Output a symbolic value from the enum if found, else just print as int32. */
12373static bool textprinter_putenum(void *closure, const void *handler_data,
12374 int32_t val) {
12375 upb_textprinter *p = closure;
12376 const upb_fielddef *f = handler_data;
12377 const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
12378 const char *label = upb_enumdef_iton(enum_def, val);
12379 if (label) {
12380 indent(p);
12381 putf(p, "%s: %s", upb_fielddef_name(f), label);
12382 endfield(p);
12383 } else {
12384 if (!textprinter_putint32(closure, handler_data, val))
12385 return false;
12386 }
12387 return true;
12388}
12389
12390static void *textprinter_startstr(void *closure, const void *handler_data,
12391 size_t size_hint) {
12392 upb_textprinter *p = closure;
12393 const upb_fielddef *f = handler_data;
12394 UPB_UNUSED(size_hint);
12395 indent(p);
12396 putf(p, "%s: \"", upb_fielddef_name(f));
12397 return p;
12398}
12399
12400static bool textprinter_endstr(void *closure, const void *handler_data) {
12401 upb_textprinter *p = closure;
12402 UPB_UNUSED(handler_data);
12403 putf(p, "\"");
12404 endfield(p);
12405 return true;
12406}
12407
12408static size_t textprinter_putstr(void *closure, const void *hd, const char *buf,
12409 size_t len, const upb_bufhandle *handle) {
12410 upb_textprinter *p = closure;
12411 const upb_fielddef *f = hd;
12412 UPB_UNUSED(handle);
12413 CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING));
12414 return len;
12415err:
12416 return 0;
12417}
12418
12419static void *textprinter_startsubmsg(void *closure, const void *handler_data) {
12420 upb_textprinter *p = closure;
12421 const char *name = handler_data;
12422 CHECK(indent(p));
12423 putf(p, "%s {%c", name, p->single_line_ ? ' ' : '\n');
12424 p->indent_depth_++;
12425 return p;
12426err:
12427 return UPB_BREAK;
12428}
12429
12430static bool textprinter_endsubmsg(void *closure, const void *handler_data) {
12431 upb_textprinter *p = closure;
12432 UPB_UNUSED(handler_data);
12433 p->indent_depth_--;
12434 CHECK(indent(p));
12435 upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL);
12436 CHECK(endfield(p));
12437 return true;
12438err:
12439 return false;
12440}
12441
12442static void onmreg(const void *c, upb_handlers *h) {
12443 const upb_msgdef *m = upb_handlers_msgdef(h);
12444 upb_msg_field_iter i;
12445 UPB_UNUSED(c);
12446
12447 upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
12448 upb_handlers_setendmsg(h, textprinter_endmsg, NULL);
12449
12450 for(upb_msg_field_begin(&i, m);
12451 !upb_msg_field_done(&i);
12452 upb_msg_field_next(&i)) {
12453 upb_fielddef *f = upb_msg_iter_field(&i);
12454 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
12455 upb_handlerattr_sethandlerdata(&attr, f);
12456 switch (upb_fielddef_type(f)) {
12457 case UPB_TYPE_INT32:
12458 upb_handlers_setint32(h, f, textprinter_putint32, &attr);
12459 break;
12460 case UPB_TYPE_INT64:
12461 upb_handlers_setint64(h, f, textprinter_putint64, &attr);
12462 break;
12463 case UPB_TYPE_UINT32:
12464 upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
12465 break;
12466 case UPB_TYPE_UINT64:
12467 upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
12468 break;
12469 case UPB_TYPE_FLOAT:
12470 upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
12471 break;
12472 case UPB_TYPE_DOUBLE:
12473 upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
12474 break;
12475 case UPB_TYPE_BOOL:
12476 upb_handlers_setbool(h, f, textprinter_putbool, &attr);
12477 break;
12478 case UPB_TYPE_STRING:
12479 case UPB_TYPE_BYTES:
12480 upb_handlers_setstartstr(h, f, textprinter_startstr, &attr);
12481 upb_handlers_setstring(h, f, textprinter_putstr, &attr);
12482 upb_handlers_setendstr(h, f, textprinter_endstr, &attr);
12483 break;
12484 case UPB_TYPE_MESSAGE: {
12485 const char *name =
12486 upb_fielddef_istagdelim(f)
12487 ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
12488 : upb_fielddef_name(f);
12489 upb_handlerattr_sethandlerdata(&attr, name);
12490 upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
12491 upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
12492 break;
12493 }
12494 case UPB_TYPE_ENUM:
12495 upb_handlers_setint32(h, f, textprinter_putenum, &attr);
12496 break;
12497 }
12498 }
12499}
12500
12501static void textprinter_reset(upb_textprinter *p, bool single_line) {
12502 p->single_line_ = single_line;
12503 p->indent_depth_ = 0;
12504}
12505
12506
12507/* Public API *****************************************************************/
12508
12509upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
12510 upb_bytessink *output) {
12511 upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter));
12512 if (!p) return NULL;
12513
12514 p->output_ = output;
12515 upb_sink_reset(&p->input_, h, p);
12516 textprinter_reset(p, false);
12517
12518 return p;
12519}
12520
12521const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
12522 const void *owner) {
12523 return upb_handlers_newfrozen(m, owner, &onmreg, NULL);
12524}
12525
12526upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
12527
12528void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) {
12529 p->single_line_ = single_line;
12530}
12531
12532
12533/* Index is descriptor type. */
12534const uint8_t upb_pb_native_wire_types[] = {
12535 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
12536 UPB_WIRE_TYPE_64BIT, /* DOUBLE */
12537 UPB_WIRE_TYPE_32BIT, /* FLOAT */
12538 UPB_WIRE_TYPE_VARINT, /* INT64 */
12539 UPB_WIRE_TYPE_VARINT, /* UINT64 */
12540 UPB_WIRE_TYPE_VARINT, /* INT32 */
12541 UPB_WIRE_TYPE_64BIT, /* FIXED64 */
12542 UPB_WIRE_TYPE_32BIT, /* FIXED32 */
12543 UPB_WIRE_TYPE_VARINT, /* BOOL */
12544 UPB_WIRE_TYPE_DELIMITED, /* STRING */
12545 UPB_WIRE_TYPE_START_GROUP, /* GROUP */
12546 UPB_WIRE_TYPE_DELIMITED, /* MESSAGE */
12547 UPB_WIRE_TYPE_DELIMITED, /* BYTES */
12548 UPB_WIRE_TYPE_VARINT, /* UINT32 */
12549 UPB_WIRE_TYPE_VARINT, /* ENUM */
12550 UPB_WIRE_TYPE_32BIT, /* SFIXED32 */
12551 UPB_WIRE_TYPE_64BIT, /* SFIXED64 */
12552 UPB_WIRE_TYPE_VARINT, /* SINT32 */
12553 UPB_WIRE_TYPE_VARINT, /* SINT64 */
12554};
12555
12556/* A basic branch-based decoder, uses 32-bit values to get good performance
12557 * on 32-bit architectures (but performs well on 64-bits also).
12558 * This scheme comes from the original Google Protobuf implementation
12559 * (proto2). */
12560upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r) {
12561 upb_decoderet err = {NULL, 0};
12562 const char *p = r.p;
12563 uint32_t low = (uint32_t)r.val;
12564 uint32_t high = 0;
12565 uint32_t b;
12566 b = *(p++); low |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
12567 b = *(p++); low |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
12568 b = *(p++); low |= (b & 0x7fU) << 28;
12569 high = (b & 0x7fU) >> 4; if (!(b & 0x80)) goto done;
12570 b = *(p++); high |= (b & 0x7fU) << 3; if (!(b & 0x80)) goto done;
12571 b = *(p++); high |= (b & 0x7fU) << 10; if (!(b & 0x80)) goto done;
12572 b = *(p++); high |= (b & 0x7fU) << 17; if (!(b & 0x80)) goto done;
12573 b = *(p++); high |= (b & 0x7fU) << 24; if (!(b & 0x80)) goto done;
12574 b = *(p++); high |= (b & 0x7fU) << 31; if (!(b & 0x80)) goto done;
12575 return err;
12576
12577done:
12578 r.val = ((uint64_t)high << 32) | low;
12579 r.p = p;
12580 return r;
12581}
12582
12583/* Like the previous, but uses 64-bit values. */
12584upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r) {
12585 const char *p = r.p;
12586 uint64_t val = r.val;
12587 uint64_t b;
12588 upb_decoderet err = {NULL, 0};
12589 b = *(p++); val |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
12590 b = *(p++); val |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
12591 b = *(p++); val |= (b & 0x7fU) << 28; if (!(b & 0x80)) goto done;
12592 b = *(p++); val |= (b & 0x7fU) << 35; if (!(b & 0x80)) goto done;
12593 b = *(p++); val |= (b & 0x7fU) << 42; if (!(b & 0x80)) goto done;
12594 b = *(p++); val |= (b & 0x7fU) << 49; if (!(b & 0x80)) goto done;
12595 b = *(p++); val |= (b & 0x7fU) << 56; if (!(b & 0x80)) goto done;
12596 b = *(p++); val |= (b & 0x7fU) << 63; if (!(b & 0x80)) goto done;
12597 return err;
12598
12599done:
12600 r.val = val;
12601 r.p = p;
12602 return r;
12603}
12604
Paul Yang8faa7782018-12-26 10:36:09 -080012605#line 1 "upb/json/parser.rl"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012606/*
12607** upb::json::Parser (upb_json_parser)
12608**
12609** A parser that uses the Ragel State Machine Compiler to generate
12610** the finite automata.
12611**
12612** Ragel only natively handles regular languages, but we can manually
12613** program it a bit to handle context-free languages like JSON, by using
12614** the "fcall" and "fret" constructs.
12615**
12616** This parser can handle the basics, but needs several things to be fleshed
12617** out:
12618**
12619** - handling of unicode escape sequences (including high surrogate pairs).
12620** - properly check and report errors for unknown fields, stack overflow,
12621** improper array nesting (or lack of nesting).
12622** - handling of base64 sequences with padding characters.
12623** - handling of push-back (non-success returns from sink functions).
12624** - handling of keys/escape-sequences/etc that span input buffers.
12625*/
12626
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012627#include <errno.h>
Paul Yang60327462017-10-09 12:39:13 -070012628#include <float.h>
12629#include <math.h>
Paul Yange0e54662016-09-15 11:09:01 -070012630#include <stdint.h>
Paul Yang9bda1f12018-09-22 18:57:43 -070012631#include <stdio.h>
Paul Yange0e54662016-09-15 11:09:01 -070012632#include <stdlib.h>
12633#include <string.h>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012634
Paul Yang9bda1f12018-09-22 18:57:43 -070012635#include <time.h>
12636
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012637
12638#define UPB_JSON_MAX_DEPTH 64
12639
Paul Yang9bda1f12018-09-22 18:57:43 -070012640/* Type of value message */
12641enum {
12642 VALUE_NULLVALUE = 0,
12643 VALUE_NUMBERVALUE = 1,
12644 VALUE_STRINGVALUE = 2,
12645 VALUE_BOOLVALUE = 3,
12646 VALUE_STRUCTVALUE = 4,
12647 VALUE_LISTVALUE = 5
12648};
Bo Yange3ee7162018-08-10 18:09:02 +000012649
12650/* Forward declare */
12651static bool is_top_level(upb_json_parser *p);
Paul Yang9bda1f12018-09-22 18:57:43 -070012652static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type);
12653static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type);
Bo Yange3ee7162018-08-10 18:09:02 +000012654
12655static bool is_number_wrapper_object(upb_json_parser *p);
12656static bool does_number_wrapper_start(upb_json_parser *p);
12657static bool does_number_wrapper_end(upb_json_parser *p);
12658
12659static bool is_string_wrapper_object(upb_json_parser *p);
12660static bool does_string_wrapper_start(upb_json_parser *p);
12661static bool does_string_wrapper_end(upb_json_parser *p);
12662
Paul Yangc4f2a922019-01-17 10:18:43 -080012663static bool is_fieldmask_object(upb_json_parser *p);
12664static bool does_fieldmask_start(upb_json_parser *p);
12665static bool does_fieldmask_end(upb_json_parser *p);
12666static void start_fieldmask_object(upb_json_parser *p);
12667static void end_fieldmask_object(upb_json_parser *p);
12668
Bo Yange3ee7162018-08-10 18:09:02 +000012669static void start_wrapper_object(upb_json_parser *p);
12670static void end_wrapper_object(upb_json_parser *p);
12671
Paul Yang9bda1f12018-09-22 18:57:43 -070012672static void start_value_object(upb_json_parser *p, int value_type);
12673static void end_value_object(upb_json_parser *p);
12674
12675static void start_listvalue_object(upb_json_parser *p);
12676static void end_listvalue_object(upb_json_parser *p);
12677
12678static void start_structvalue_object(upb_json_parser *p);
12679static void end_structvalue_object(upb_json_parser *p);
12680
12681static void start_object(upb_json_parser *p);
12682static void end_object(upb_json_parser *p);
12683
Paul Yang8faa7782018-12-26 10:36:09 -080012684static void start_any_object(upb_json_parser *p, const char *ptr);
12685static bool end_any_object(upb_json_parser *p, const char *ptr);
12686
Bo Yange3ee7162018-08-10 18:09:02 +000012687static bool start_subobject(upb_json_parser *p);
12688static void end_subobject(upb_json_parser *p);
12689
Paul Yang9bda1f12018-09-22 18:57:43 -070012690static void start_member(upb_json_parser *p);
12691static void end_member(upb_json_parser *p);
12692static bool end_membername(upb_json_parser *p);
12693
Paul Yang8faa7782018-12-26 10:36:09 -080012694static void start_any_member(upb_json_parser *p, const char *ptr);
12695static void end_any_member(upb_json_parser *p, const char *ptr);
12696static bool end_any_membername(upb_json_parser *p);
12697
12698size_t parse(void *closure, const void *hd, const char *buf, size_t size,
12699 const upb_bufhandle *handle);
12700static bool end(void *closure, const void *hd);
12701
Bo Yange3ee7162018-08-10 18:09:02 +000012702static const char eof_ch = 'e';
12703
Paul Yang8faa7782018-12-26 10:36:09 -080012704/* stringsink */
12705typedef struct {
12706 upb_byteshandler handler;
12707 upb_bytessink sink;
12708 char *ptr;
12709 size_t len, size;
12710} upb_stringsink;
12711
12712
12713static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
12714 upb_stringsink *sink = _sink;
12715 sink->len = 0;
12716 UPB_UNUSED(hd);
12717 UPB_UNUSED(size_hint);
12718 return sink;
12719}
12720
12721static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
12722 size_t len, const upb_bufhandle *handle) {
12723 upb_stringsink *sink = _sink;
12724 size_t new_size = sink->size;
12725
12726 UPB_UNUSED(hd);
12727 UPB_UNUSED(handle);
12728
12729 while (sink->len + len > new_size) {
12730 new_size *= 2;
12731 }
12732
12733 if (new_size != sink->size) {
12734 sink->ptr = realloc(sink->ptr, new_size);
12735 sink->size = new_size;
12736 }
12737
12738 memcpy(sink->ptr + sink->len, ptr, len);
12739 sink->len += len;
12740
12741 return len;
12742}
12743
12744void upb_stringsink_init(upb_stringsink *sink) {
12745 upb_byteshandler_init(&sink->handler);
12746 upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
12747 upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
12748
12749 upb_bytessink_reset(&sink->sink, &sink->handler, sink);
12750
12751 sink->size = 32;
12752 sink->ptr = malloc(sink->size);
12753 sink->len = 0;
12754}
12755
12756void upb_stringsink_uninit(upb_stringsink *sink) { free(sink->ptr); }
12757
12758typedef struct {
12759 /* For encoding Any value field in binary format. */
12760 const upb_handlers *encoder_handlers;
12761 upb_pb_encoder *encoder;
12762 upb_stringsink stringsink;
12763
12764 /* For decoding Any value field in json format. */
12765 upb_json_parsermethod *parser_method;
12766 upb_json_parser* parser;
12767 upb_sink sink;
12768
12769 /* Mark the range of uninterpreted values in json input before type url. */
12770 const char *before_type_url_start;
12771 const char *before_type_url_end;
12772
12773 /* Mark the range of uninterpreted values in json input after type url. */
12774 const char *after_type_url_start;
12775} upb_jsonparser_any_frame;
12776
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012777typedef struct {
12778 upb_sink sink;
12779
12780 /* The current message in which we're parsing, and the field whose value we're
12781 * expecting next. */
12782 const upb_msgdef *m;
12783 const upb_fielddef *f;
12784
Paul Yange0e54662016-09-15 11:09:01 -070012785 /* The table mapping json name to fielddef for this message. */
12786 upb_strtable *name_table;
12787
Paul Yang4b145b12019-03-12 10:56:58 -070012788 /* We are in a repeated-field context. We need this flag to decide whether to
12789 * handle the array as a normal repeated field or a
12790 * google.protobuf.ListValue/google.protobuf.Value. */
12791 bool is_repeated;
12792
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012793 /* We are in a repeated-field context, ready to emit mapentries as
12794 * submessages. This flag alters the start-of-object (open-brace) behavior to
12795 * begin a sequence of mapentry messages rather than a single submessage. */
12796 bool is_map;
12797
12798 /* We are in a map-entry message context. This flag is set when parsing the
12799 * value field of a single map entry and indicates to all value-field parsers
12800 * (subobjects, strings, numbers, and bools) that the map-entry submessage
12801 * should end as soon as the value is parsed. */
12802 bool is_mapentry;
12803
12804 /* If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
12805 * message's map field that we're currently parsing. This differs from |f|
12806 * because |f| is the field in the *current* message (i.e., the map-entry
12807 * message itself), not the parent's field that leads to this map. */
12808 const upb_fielddef *mapfield;
Paul Yangd2d4b402018-10-12 13:46:26 -070012809
Paul Yang8faa7782018-12-26 10:36:09 -080012810 /* We are in an Any message context. This flag is set when parsing the Any
12811 * message and indicates to all field parsers (subobjects, strings, numbers,
12812 * and bools) that the parsed field should be serialized as binary data or
12813 * cached (type url not found yet). */
12814 bool is_any;
12815
12816 /* The type of packed message in Any. */
12817 upb_jsonparser_any_frame *any_frame;
12818
Paul Yangd2d4b402018-10-12 13:46:26 -070012819 /* True if the field to be parsed is unknown. */
12820 bool is_unknown_field;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012821} upb_jsonparser_frame;
12822
12823struct upb_json_parser {
12824 upb_env *env;
Paul Yange0e54662016-09-15 11:09:01 -070012825 const upb_json_parsermethod *method;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012826 upb_bytessink input_;
12827
12828 /* Stack to track the JSON scopes we are in. */
12829 upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH];
12830 upb_jsonparser_frame *top;
12831 upb_jsonparser_frame *limit;
12832
12833 upb_status status;
12834
12835 /* Ragel's internal parsing stack for the parsing state machine. */
12836 int current_state;
12837 int parser_stack[UPB_JSON_MAX_DEPTH];
12838 int parser_top;
12839
12840 /* The handle for the current buffer. */
12841 const upb_bufhandle *handle;
12842
12843 /* Accumulate buffer. See details in parser.rl. */
12844 const char *accumulated;
12845 size_t accumulated_len;
12846 char *accumulate_buf;
12847 size_t accumulate_buf_size;
12848
12849 /* Multi-part text data. See details in parser.rl. */
12850 int multipart_state;
12851 upb_selector_t string_selector;
12852
12853 /* Input capture. See details in parser.rl. */
12854 const char *capture;
12855
12856 /* Intermediate result of parsing a unicode escape sequence. */
12857 uint32_t digit;
Paul Yang26eeec92018-07-09 14:29:23 -070012858
Paul Yang8faa7782018-12-26 10:36:09 -080012859 /* For resolve type url in Any. */
12860 const upb_symtab *symtab;
12861
Paul Yang26eeec92018-07-09 14:29:23 -070012862 /* Whether to proceed if unknown field is met. */
12863 bool ignore_json_unknown;
Paul Yang9bda1f12018-09-22 18:57:43 -070012864
12865 /* Cache for parsing timestamp due to base and zone are handled in different
12866 * handlers. */
12867 struct tm tm;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012868};
12869
Paul Yange0e54662016-09-15 11:09:01 -070012870struct upb_json_parsermethod {
12871 upb_refcounted base;
12872
12873 upb_byteshandler input_handler_;
12874
12875 /* Mainly for the purposes of refcounting, so all the fielddefs we point
12876 * to stay alive. */
12877 const upb_msgdef *msg;
12878
12879 /* Keys are upb_msgdef*, values are upb_strtable (json_name -> fielddef) */
12880 upb_inttable name_tables;
12881};
12882
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012883#define PARSER_CHECK_RETURN(x) if (!(x)) return false
12884
Paul Yang8faa7782018-12-26 10:36:09 -080012885static void json_parser_any_frame_reset(upb_jsonparser_any_frame *frame) {
12886 frame->encoder_handlers = NULL;
12887 frame->encoder = NULL;
12888 frame->parser_method = NULL;
12889 frame->parser = NULL;
12890 frame->before_type_url_start = NULL;
12891 frame->before_type_url_end = NULL;
12892 frame->after_type_url_start = NULL;
12893}
12894
12895static void json_parser_any_frame_set_payload_type(
12896 upb_json_parser *p,
12897 upb_jsonparser_any_frame *frame,
12898 const upb_msgdef *payload_type) {
12899 /* Initialize encoder. */
12900 frame->encoder_handlers =
12901 upb_pb_encoder_newhandlers(payload_type, &frame->encoder_handlers);
12902 upb_stringsink_init(&frame->stringsink);
12903 frame->encoder =
12904 upb_pb_encoder_create(
12905 p->env, frame->encoder_handlers,
12906 &frame->stringsink.sink);
12907
12908 /* Initialize parser. */
12909 frame->parser_method =
12910 upb_json_parsermethod_new(payload_type, &frame->parser_method);
12911 upb_sink_reset(&frame->sink, frame->encoder_handlers, frame->encoder);
12912 frame->parser =
12913 upb_json_parser_create(p->env, frame->parser_method, p->symtab,
12914 &frame->sink, p->ignore_json_unknown);
12915}
12916
12917static void json_parser_any_frame_free(upb_jsonparser_any_frame *frame) {
12918 upb_handlers_unref(frame->encoder_handlers,
12919 &frame->encoder_handlers);
12920 upb_json_parsermethod_unref(frame->parser_method,
12921 &frame->parser_method);
12922 upb_stringsink_uninit(&frame->stringsink);
12923}
12924
12925static bool json_parser_any_frame_has_type_url(
12926 upb_jsonparser_any_frame *frame) {
12927 return frame->encoder != NULL;
12928}
12929
12930static bool json_parser_any_frame_has_value_before_type_url(
12931 upb_jsonparser_any_frame *frame) {
12932 return frame->before_type_url_start != frame->before_type_url_end;
12933}
12934
12935static bool json_parser_any_frame_has_value_after_type_url(
12936 upb_jsonparser_any_frame *frame) {
12937 return frame->after_type_url_start != NULL;
12938}
12939
12940static bool json_parser_any_frame_has_value(
12941 upb_jsonparser_any_frame *frame) {
12942 return json_parser_any_frame_has_value_before_type_url(frame) ||
12943 json_parser_any_frame_has_value_after_type_url(frame);
12944}
12945
12946static void json_parser_any_frame_set_before_type_url_end(
12947 upb_jsonparser_any_frame *frame,
12948 const char *ptr) {
12949 if (frame->encoder == NULL) {
12950 frame->before_type_url_end = ptr;
12951 }
12952}
12953
12954static void json_parser_any_frame_set_after_type_url_start_once(
12955 upb_jsonparser_any_frame *frame,
12956 const char *ptr) {
12957 if (json_parser_any_frame_has_type_url(frame) &&
12958 frame->after_type_url_start == NULL) {
12959 frame->after_type_url_start = ptr;
12960 }
12961}
12962
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012963/* Used to signal that a capture has been suspended. */
12964static char suspend_capture;
12965
12966static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
12967 upb_handlertype_t type) {
12968 upb_selector_t sel;
12969 bool ok = upb_handlers_getselector(p->top->f, type, &sel);
Paul Yange0e54662016-09-15 11:09:01 -070012970 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012971 return sel;
12972}
12973
12974static upb_selector_t parser_getsel(upb_json_parser *p) {
12975 return getsel_for_handlertype(
12976 p, upb_handlers_getprimitivehandlertype(p->top->f));
12977}
12978
12979static bool check_stack(upb_json_parser *p) {
12980 if ((p->top + 1) == p->limit) {
12981 upb_status_seterrmsg(&p->status, "Nesting too deep");
12982 upb_env_reporterror(p->env, &p->status);
12983 return false;
12984 }
12985
12986 return true;
12987}
12988
Paul Yange0e54662016-09-15 11:09:01 -070012989static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
12990 upb_value v;
12991 bool ok = upb_inttable_lookupptr(&p->method->name_tables, frame->m, &v);
12992 UPB_ASSERT(ok);
12993 frame->name_table = upb_value_getptr(v);
12994}
12995
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070012996/* There are GCC/Clang built-ins for overflow checking which we could start
12997 * using if there was any performance benefit to it. */
12998
12999static bool checked_add(size_t a, size_t b, size_t *c) {
13000 if (SIZE_MAX - a < b) return false;
13001 *c = a + b;
13002 return true;
13003}
13004
13005static size_t saturating_multiply(size_t a, size_t b) {
13006 /* size_t is unsigned, so this is defined behavior even on overflow. */
13007 size_t ret = a * b;
13008 if (b != 0 && ret / b != a) {
13009 ret = SIZE_MAX;
13010 }
13011 return ret;
13012}
13013
13014
13015/* Base64 decoding ************************************************************/
13016
13017/* TODO(haberman): make this streaming. */
13018
13019static const signed char b64table[] = {
13020 -1, -1, -1, -1, -1, -1, -1, -1,
13021 -1, -1, -1, -1, -1, -1, -1, -1,
13022 -1, -1, -1, -1, -1, -1, -1, -1,
13023 -1, -1, -1, -1, -1, -1, -1, -1,
13024 -1, -1, -1, -1, -1, -1, -1, -1,
13025 -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */,
13026 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
13027 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1,
13028 -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
13029 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
13030 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
13031 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1,
13032 -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
13033 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
13034 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
13035 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1,
13036 -1, -1, -1, -1, -1, -1, -1, -1,
13037 -1, -1, -1, -1, -1, -1, -1, -1,
13038 -1, -1, -1, -1, -1, -1, -1, -1,
13039 -1, -1, -1, -1, -1, -1, -1, -1,
13040 -1, -1, -1, -1, -1, -1, -1, -1,
13041 -1, -1, -1, -1, -1, -1, -1, -1,
13042 -1, -1, -1, -1, -1, -1, -1, -1,
13043 -1, -1, -1, -1, -1, -1, -1, -1,
13044 -1, -1, -1, -1, -1, -1, -1, -1,
13045 -1, -1, -1, -1, -1, -1, -1, -1,
13046 -1, -1, -1, -1, -1, -1, -1, -1,
13047 -1, -1, -1, -1, -1, -1, -1, -1,
13048 -1, -1, -1, -1, -1, -1, -1, -1,
13049 -1, -1, -1, -1, -1, -1, -1, -1,
13050 -1, -1, -1, -1, -1, -1, -1, -1,
13051 -1, -1, -1, -1, -1, -1, -1, -1
13052};
13053
13054/* Returns the table value sign-extended to 32 bits. Knowing that the upper
13055 * bits will be 1 for unrecognized characters makes it easier to check for
13056 * this error condition later (see below). */
13057int32_t b64lookup(unsigned char ch) { return b64table[ch]; }
13058
13059/* Returns true if the given character is not a valid base64 character or
13060 * padding. */
13061bool nonbase64(unsigned char ch) { return b64lookup(ch) == -1 && ch != '='; }
13062
13063static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
13064 size_t len) {
13065 const char *limit = ptr + len;
13066 for (; ptr < limit; ptr += 4) {
13067 uint32_t val;
13068 char output[3];
13069
13070 if (limit - ptr < 4) {
13071 upb_status_seterrf(&p->status,
13072 "Base64 input for bytes field not a multiple of 4: %s",
13073 upb_fielddef_name(p->top->f));
13074 upb_env_reporterror(p->env, &p->status);
13075 return false;
13076 }
13077
13078 val = b64lookup(ptr[0]) << 18 |
13079 b64lookup(ptr[1]) << 12 |
13080 b64lookup(ptr[2]) << 6 |
13081 b64lookup(ptr[3]);
13082
13083 /* Test the upper bit; returns true if any of the characters returned -1. */
13084 if (val & 0x80000000) {
13085 goto otherchar;
13086 }
13087
13088 output[0] = val >> 16;
13089 output[1] = (val >> 8) & 0xff;
13090 output[2] = val & 0xff;
13091 upb_sink_putstring(&p->top->sink, sel, output, 3, NULL);
13092 }
13093 return true;
13094
13095otherchar:
13096 if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) ||
13097 nonbase64(ptr[3]) ) {
13098 upb_status_seterrf(&p->status,
13099 "Non-base64 characters in bytes field: %s",
13100 upb_fielddef_name(p->top->f));
13101 upb_env_reporterror(p->env, &p->status);
13102 return false;
13103 } if (ptr[2] == '=') {
13104 uint32_t val;
13105 char output;
13106
13107 /* Last group contains only two input bytes, one output byte. */
13108 if (ptr[0] == '=' || ptr[1] == '=' || ptr[3] != '=') {
13109 goto badpadding;
13110 }
13111
13112 val = b64lookup(ptr[0]) << 18 |
13113 b64lookup(ptr[1]) << 12;
13114
Paul Yange0e54662016-09-15 11:09:01 -070013115 UPB_ASSERT(!(val & 0x80000000));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013116 output = val >> 16;
13117 upb_sink_putstring(&p->top->sink, sel, &output, 1, NULL);
13118 return true;
13119 } else {
13120 uint32_t val;
13121 char output[2];
13122
13123 /* Last group contains only three input bytes, two output bytes. */
13124 if (ptr[0] == '=' || ptr[1] == '=' || ptr[2] == '=') {
13125 goto badpadding;
13126 }
13127
13128 val = b64lookup(ptr[0]) << 18 |
13129 b64lookup(ptr[1]) << 12 |
13130 b64lookup(ptr[2]) << 6;
13131
13132 output[0] = val >> 16;
13133 output[1] = (val >> 8) & 0xff;
13134 upb_sink_putstring(&p->top->sink, sel, output, 2, NULL);
13135 return true;
13136 }
13137
13138badpadding:
13139 upb_status_seterrf(&p->status,
13140 "Incorrect base64 padding for field: %s (%.*s)",
13141 upb_fielddef_name(p->top->f),
13142 4, ptr);
13143 upb_env_reporterror(p->env, &p->status);
13144 return false;
13145}
13146
13147
13148/* Accumulate buffer **********************************************************/
13149
13150/* Functionality for accumulating a buffer.
13151 *
13152 * Some parts of the parser need an entire value as a contiguous string. For
13153 * example, to look up a member name in a hash table, or to turn a string into
13154 * a number, the relevant library routines need the input string to be in
13155 * contiguous memory, even if the value spanned two or more buffers in the
13156 * input. These routines handle that.
13157 *
13158 * In the common case we can just point to the input buffer to get this
13159 * contiguous string and avoid any actual copy. So we optimistically begin
13160 * this way. But there are a few cases where we must instead copy into a
13161 * separate buffer:
13162 *
13163 * 1. The string was not contiguous in the input (it spanned buffers).
13164 *
13165 * 2. The string included escape sequences that need to be interpreted to get
13166 * the true value in a contiguous buffer. */
13167
13168static void assert_accumulate_empty(upb_json_parser *p) {
Paul Yange0e54662016-09-15 11:09:01 -070013169 UPB_ASSERT(p->accumulated == NULL);
13170 UPB_ASSERT(p->accumulated_len == 0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013171}
13172
13173static void accumulate_clear(upb_json_parser *p) {
13174 p->accumulated = NULL;
13175 p->accumulated_len = 0;
13176}
13177
13178/* Used internally by accumulate_append(). */
13179static bool accumulate_realloc(upb_json_parser *p, size_t need) {
13180 void *mem;
13181 size_t old_size = p->accumulate_buf_size;
13182 size_t new_size = UPB_MAX(old_size, 128);
13183 while (new_size < need) {
13184 new_size = saturating_multiply(new_size, 2);
13185 }
13186
13187 mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size);
13188 if (!mem) {
13189 upb_status_seterrmsg(&p->status, "Out of memory allocating buffer.");
13190 upb_env_reporterror(p->env, &p->status);
13191 return false;
13192 }
13193
13194 p->accumulate_buf = mem;
13195 p->accumulate_buf_size = new_size;
13196 return true;
13197}
13198
13199/* Logically appends the given data to the append buffer.
13200 * If "can_alias" is true, we will try to avoid actually copying, but the buffer
13201 * must be valid until the next accumulate_append() call (if any). */
13202static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
13203 bool can_alias) {
13204 size_t need;
13205
13206 if (!p->accumulated && can_alias) {
13207 p->accumulated = buf;
13208 p->accumulated_len = len;
13209 return true;
13210 }
13211
13212 if (!checked_add(p->accumulated_len, len, &need)) {
13213 upb_status_seterrmsg(&p->status, "Integer overflow.");
13214 upb_env_reporterror(p->env, &p->status);
13215 return false;
13216 }
13217
13218 if (need > p->accumulate_buf_size && !accumulate_realloc(p, need)) {
13219 return false;
13220 }
13221
13222 if (p->accumulated != p->accumulate_buf) {
13223 memcpy(p->accumulate_buf, p->accumulated, p->accumulated_len);
13224 p->accumulated = p->accumulate_buf;
13225 }
13226
13227 memcpy(p->accumulate_buf + p->accumulated_len, buf, len);
13228 p->accumulated_len += len;
13229 return true;
13230}
13231
13232/* Returns a pointer to the data accumulated since the last accumulate_clear()
13233 * call, and writes the length to *len. This with point either to the input
13234 * buffer or a temporary accumulate buffer. */
13235static const char *accumulate_getptr(upb_json_parser *p, size_t *len) {
Paul Yange0e54662016-09-15 11:09:01 -070013236 UPB_ASSERT(p->accumulated);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013237 *len = p->accumulated_len;
13238 return p->accumulated;
13239}
13240
13241
13242/* Mult-part text data ********************************************************/
13243
13244/* When we have text data in the input, it can often come in multiple segments.
13245 * For example, there may be some raw string data followed by an escape
13246 * sequence. The two segments are processed with different logic. Also buffer
13247 * seams in the input can cause multiple segments.
13248 *
13249 * As we see segments, there are two main cases for how we want to process them:
13250 *
13251 * 1. we want to push the captured input directly to string handlers.
13252 *
13253 * 2. we need to accumulate all the parts into a contiguous buffer for further
13254 * processing (field name lookup, string->number conversion, etc). */
13255
13256/* This is the set of states for p->multipart_state. */
13257enum {
13258 /* We are not currently processing multipart data. */
13259 MULTIPART_INACTIVE = 0,
13260
13261 /* We are processing multipart data by accumulating it into a contiguous
13262 * buffer. */
13263 MULTIPART_ACCUMULATE = 1,
13264
13265 /* We are processing multipart data by pushing each part directly to the
13266 * current string handlers. */
13267 MULTIPART_PUSHEAGERLY = 2
13268};
13269
13270/* Start a multi-part text value where we accumulate the data for processing at
13271 * the end. */
13272static void multipart_startaccum(upb_json_parser *p) {
13273 assert_accumulate_empty(p);
Paul Yange0e54662016-09-15 11:09:01 -070013274 UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013275 p->multipart_state = MULTIPART_ACCUMULATE;
13276}
13277
13278/* Start a multi-part text value where we immediately push text data to a string
13279 * value with the given selector. */
13280static void multipart_start(upb_json_parser *p, upb_selector_t sel) {
13281 assert_accumulate_empty(p);
Paul Yange0e54662016-09-15 11:09:01 -070013282 UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013283 p->multipart_state = MULTIPART_PUSHEAGERLY;
13284 p->string_selector = sel;
13285}
13286
13287static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
13288 bool can_alias) {
13289 switch (p->multipart_state) {
13290 case MULTIPART_INACTIVE:
13291 upb_status_seterrmsg(
13292 &p->status, "Internal error: unexpected state MULTIPART_INACTIVE");
13293 upb_env_reporterror(p->env, &p->status);
13294 return false;
13295
13296 case MULTIPART_ACCUMULATE:
13297 if (!accumulate_append(p, buf, len, can_alias)) {
13298 return false;
13299 }
13300 break;
13301
13302 case MULTIPART_PUSHEAGERLY: {
13303 const upb_bufhandle *handle = can_alias ? p->handle : NULL;
13304 upb_sink_putstring(&p->top->sink, p->string_selector, buf, len, handle);
13305 break;
13306 }
13307 }
13308
13309 return true;
13310}
13311
13312/* Note: this invalidates the accumulate buffer! Call only after reading its
13313 * contents. */
13314static void multipart_end(upb_json_parser *p) {
Paul Yange0e54662016-09-15 11:09:01 -070013315 UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013316 p->multipart_state = MULTIPART_INACTIVE;
13317 accumulate_clear(p);
13318}
13319
13320
13321/* Input capture **************************************************************/
13322
13323/* Functionality for capturing a region of the input as text. Gracefully
13324 * handles the case where a buffer seam occurs in the middle of the captured
13325 * region. */
13326
13327static void capture_begin(upb_json_parser *p, const char *ptr) {
Paul Yange0e54662016-09-15 11:09:01 -070013328 UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
13329 UPB_ASSERT(p->capture == NULL);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013330 p->capture = ptr;
13331}
13332
13333static bool capture_end(upb_json_parser *p, const char *ptr) {
Paul Yange0e54662016-09-15 11:09:01 -070013334 UPB_ASSERT(p->capture);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013335 if (multipart_text(p, p->capture, ptr - p->capture, true)) {
13336 p->capture = NULL;
13337 return true;
13338 } else {
13339 return false;
13340 }
13341}
13342
13343/* This is called at the end of each input buffer (ie. when we have hit a
13344 * buffer seam). If we are in the middle of capturing the input, this
13345 * processes the unprocessed capture region. */
13346static void capture_suspend(upb_json_parser *p, const char **ptr) {
13347 if (!p->capture) return;
13348
13349 if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
13350 /* We use this as a signal that we were in the middle of capturing, and
13351 * that capturing should resume at the beginning of the next buffer.
13352 *
13353 * We can't use *ptr here, because we have no guarantee that this pointer
13354 * will be valid when we resume (if the underlying memory is freed, then
13355 * using the pointer at all, even to compare to NULL, is likely undefined
13356 * behavior). */
13357 p->capture = &suspend_capture;
13358 } else {
13359 /* Need to back up the pointer to the beginning of the capture, since
13360 * we were not able to actually preserve it. */
13361 *ptr = p->capture;
13362 }
13363}
13364
13365static void capture_resume(upb_json_parser *p, const char *ptr) {
13366 if (p->capture) {
Paul Yange0e54662016-09-15 11:09:01 -070013367 UPB_ASSERT(p->capture == &suspend_capture);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013368 p->capture = ptr;
13369 }
13370}
13371
13372
13373/* Callbacks from the parser **************************************************/
13374
13375/* These are the functions called directly from the parser itself.
13376 * We define these in the same order as their declarations in the parser. */
13377
13378static char escape_char(char in) {
13379 switch (in) {
13380 case 'r': return '\r';
13381 case 't': return '\t';
13382 case 'n': return '\n';
13383 case 'f': return '\f';
13384 case 'b': return '\b';
13385 case '/': return '/';
13386 case '"': return '"';
13387 case '\\': return '\\';
13388 default:
Paul Yange0e54662016-09-15 11:09:01 -070013389 UPB_ASSERT(0);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013390 return 'x';
13391 }
13392}
13393
13394static bool escape(upb_json_parser *p, const char *ptr) {
13395 char ch = escape_char(*ptr);
13396 return multipart_text(p, &ch, 1, false);
13397}
13398
13399static void start_hex(upb_json_parser *p) {
13400 p->digit = 0;
13401}
13402
13403static void hexdigit(upb_json_parser *p, const char *ptr) {
13404 char ch = *ptr;
13405
13406 p->digit <<= 4;
13407
13408 if (ch >= '0' && ch <= '9') {
13409 p->digit += (ch - '0');
13410 } else if (ch >= 'a' && ch <= 'f') {
13411 p->digit += ((ch - 'a') + 10);
13412 } else {
Paul Yange0e54662016-09-15 11:09:01 -070013413 UPB_ASSERT(ch >= 'A' && ch <= 'F');
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013414 p->digit += ((ch - 'A') + 10);
13415 }
13416}
13417
13418static bool end_hex(upb_json_parser *p) {
13419 uint32_t codepoint = p->digit;
13420
13421 /* emit the codepoint as UTF-8. */
13422 char utf8[3]; /* support \u0000 -- \uFFFF -- need only three bytes. */
13423 int length = 0;
13424 if (codepoint <= 0x7F) {
13425 utf8[0] = codepoint;
13426 length = 1;
13427 } else if (codepoint <= 0x07FF) {
13428 utf8[1] = (codepoint & 0x3F) | 0x80;
13429 codepoint >>= 6;
13430 utf8[0] = (codepoint & 0x1F) | 0xC0;
13431 length = 2;
13432 } else /* codepoint <= 0xFFFF */ {
13433 utf8[2] = (codepoint & 0x3F) | 0x80;
13434 codepoint >>= 6;
13435 utf8[1] = (codepoint & 0x3F) | 0x80;
13436 codepoint >>= 6;
13437 utf8[0] = (codepoint & 0x0F) | 0xE0;
13438 length = 3;
13439 }
13440 /* TODO(haberman): Handle high surrogates: if codepoint is a high surrogate
13441 * we have to wait for the next escape to get the full code point). */
13442
13443 return multipart_text(p, utf8, length, false);
13444}
13445
13446static void start_text(upb_json_parser *p, const char *ptr) {
13447 capture_begin(p, ptr);
13448}
13449
13450static bool end_text(upb_json_parser *p, const char *ptr) {
13451 return capture_end(p, ptr);
13452}
13453
Bo Yange3ee7162018-08-10 18:09:02 +000013454static bool start_number(upb_json_parser *p, const char *ptr) {
13455 if (is_top_level(p)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070013456 if (is_number_wrapper_object(p)) {
13457 start_wrapper_object(p);
13458 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13459 start_value_object(p, VALUE_NUMBERVALUE);
13460 } else {
Bo Yange3ee7162018-08-10 18:09:02 +000013461 return false;
13462 }
Bo Yange3ee7162018-08-10 18:09:02 +000013463 } else if (does_number_wrapper_start(p)) {
13464 if (!start_subobject(p)) {
13465 return false;
13466 }
13467 start_wrapper_object(p);
Paul Yang9bda1f12018-09-22 18:57:43 -070013468 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
13469 if (!start_subobject(p)) {
13470 return false;
13471 }
13472 start_value_object(p, VALUE_NUMBERVALUE);
Bo Yange3ee7162018-08-10 18:09:02 +000013473 }
13474
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013475 multipart_startaccum(p);
13476 capture_begin(p, ptr);
Bo Yange3ee7162018-08-10 18:09:02 +000013477 return true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013478}
13479
Paul Yang60327462017-10-09 12:39:13 -070013480static bool parse_number(upb_json_parser *p, bool is_quoted);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013481
Bo Yange3ee7162018-08-10 18:09:02 +000013482static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013483 if (!capture_end(p, ptr)) {
13484 return false;
13485 }
13486
Paul Yang26eeec92018-07-09 14:29:23 -070013487 if (p->top->f == NULL) {
13488 multipart_end(p);
13489 return true;
13490 }
13491
Paul Yang60327462017-10-09 12:39:13 -070013492 return parse_number(p, false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013493}
13494
Bo Yange3ee7162018-08-10 18:09:02 +000013495static bool end_number(upb_json_parser *p, const char *ptr) {
13496 if (!end_number_nontop(p, ptr)) {
13497 return false;
13498 }
13499
13500 if (does_number_wrapper_end(p)) {
13501 end_wrapper_object(p);
13502 if (!is_top_level(p)) {
13503 end_subobject(p);
13504 }
Paul Yang9bda1f12018-09-22 18:57:43 -070013505 return true;
13506 }
13507
13508 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13509 end_value_object(p);
13510 if (!is_top_level(p)) {
13511 end_subobject(p);
13512 }
13513 return true;
Bo Yange3ee7162018-08-10 18:09:02 +000013514 }
13515
13516 return true;
13517}
13518
Paul Yang60327462017-10-09 12:39:13 -070013519/* |buf| is NULL-terminated. |buf| itself will never include quotes;
13520 * |is_quoted| tells us whether this text originally appeared inside quotes. */
13521static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
13522 bool is_quoted) {
13523 size_t len = strlen(buf);
13524 const char *bufend = buf + len;
13525 char *end;
13526 upb_fieldtype_t type = upb_fielddef_type(p->top->f);
13527 double val;
13528 double dummy;
13529 double inf = 1.0 / 0.0; /* C89 does not have an INFINITY macro. */
13530
13531 errno = 0;
13532
13533 if (len == 0 || buf[0] == ' ') {
13534 return false;
13535 }
13536
13537 /* For integer types, first try parsing with integer-specific routines.
13538 * If these succeed, they will be more accurate for int64/uint64 than
13539 * strtod().
13540 */
13541 switch (type) {
13542 case UPB_TYPE_ENUM:
13543 case UPB_TYPE_INT32: {
13544 long val = strtol(buf, &end, 0);
13545 if (errno == ERANGE || end != bufend) {
13546 break;
13547 } else if (val > INT32_MAX || val < INT32_MIN) {
13548 return false;
13549 } else {
13550 upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
13551 return true;
13552 }
13553 }
13554 case UPB_TYPE_UINT32: {
13555 unsigned long val = strtoul(buf, &end, 0);
13556 if (end != bufend) {
13557 break;
13558 } else if (val > UINT32_MAX || errno == ERANGE) {
13559 return false;
13560 } else {
13561 upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
13562 return true;
13563 }
13564 }
13565 /* XXX: We can't handle [u]int64 properly on 32-bit machines because
13566 * strto[u]ll isn't in C89. */
13567 case UPB_TYPE_INT64: {
13568 long val = strtol(buf, &end, 0);
13569 if (errno == ERANGE || end != bufend) {
13570 break;
13571 } else {
13572 upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
13573 return true;
13574 }
13575 }
13576 case UPB_TYPE_UINT64: {
13577 unsigned long val = strtoul(p->accumulated, &end, 0);
13578 if (end != bufend) {
13579 break;
13580 } else if (errno == ERANGE) {
13581 return false;
13582 } else {
13583 upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
13584 return true;
13585 }
13586 }
13587 default:
13588 break;
13589 }
13590
13591 if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
13592 /* Quoted numbers for integer types are not allowed to be in double form. */
13593 return false;
13594 }
13595
13596 if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
13597 /* C89 does not have an INFINITY macro. */
13598 val = inf;
13599 } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
13600 val = -inf;
13601 } else {
13602 val = strtod(buf, &end);
13603 if (errno == ERANGE || end != bufend) {
13604 return false;
13605 }
13606 }
13607
13608 switch (type) {
13609#define CASE(capitaltype, smalltype, ctype, min, max) \
13610 case UPB_TYPE_ ## capitaltype: { \
13611 if (modf(val, &dummy) != 0 || val > max || val < min) { \
13612 return false; \
13613 } else { \
13614 upb_sink_put ## smalltype(&p->top->sink, parser_getsel(p), \
13615 (ctype)val); \
13616 return true; \
13617 } \
13618 break; \
13619 }
13620 case UPB_TYPE_ENUM:
13621 CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
13622 CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
13623 CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
13624 CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
13625#undef CASE
13626
13627 case UPB_TYPE_DOUBLE:
13628 upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
13629 return true;
13630 case UPB_TYPE_FLOAT:
13631 if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
13632 return false;
13633 } else {
13634 upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
13635 return true;
13636 }
13637 default:
13638 return false;
13639 }
13640}
13641
13642static bool parse_number(upb_json_parser *p, bool is_quoted) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013643 size_t len;
13644 const char *buf;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013645
13646 /* strtol() and friends unfortunately do not support specifying the length of
13647 * the input string, so we need to force a copy into a NULL-terminated buffer. */
13648 if (!multipart_text(p, "\0", 1, false)) {
13649 return false;
13650 }
13651
13652 buf = accumulate_getptr(p, &len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013653
Paul Yang60327462017-10-09 12:39:13 -070013654 if (parse_number_from_buffer(p, buf, is_quoted)) {
13655 multipart_end(p);
13656 return true;
13657 } else {
13658 upb_status_seterrf(&p->status, "error parsing number: %s", buf);
13659 upb_env_reporterror(p->env, &p->status);
13660 multipart_end(p);
13661 return false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013662 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013663}
13664
13665static bool parser_putbool(upb_json_parser *p, bool val) {
13666 bool ok;
13667
Paul Yang26eeec92018-07-09 14:29:23 -070013668 if (p->top->f == NULL) {
13669 return true;
13670 }
13671
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013672 if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
13673 upb_status_seterrf(&p->status,
13674 "Boolean value specified for non-bool field: %s",
13675 upb_fielddef_name(p->top->f));
13676 upb_env_reporterror(p->env, &p->status);
13677 return false;
13678 }
13679
13680 ok = upb_sink_putbool(&p->top->sink, parser_getsel(p), val);
Paul Yange0e54662016-09-15 11:09:01 -070013681 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013682
13683 return true;
13684}
13685
Bo Yange3ee7162018-08-10 18:09:02 +000013686static bool end_bool(upb_json_parser *p, bool val) {
13687 if (is_top_level(p)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070013688 if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
13689 start_wrapper_object(p);
13690 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13691 start_value_object(p, VALUE_BOOLVALUE);
13692 } else {
Bo Yange3ee7162018-08-10 18:09:02 +000013693 return false;
13694 }
Paul Yang9bda1f12018-09-22 18:57:43 -070013695 } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) {
Bo Yange3ee7162018-08-10 18:09:02 +000013696 if (!start_subobject(p)) {
13697 return false;
13698 }
13699 start_wrapper_object(p);
Paul Yang9bda1f12018-09-22 18:57:43 -070013700 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
13701 if (!start_subobject(p)) {
13702 return false;
13703 }
13704 start_value_object(p, VALUE_BOOLVALUE);
Bo Yange3ee7162018-08-10 18:09:02 +000013705 }
13706
Paul Yangd2d4b402018-10-12 13:46:26 -070013707 if (p->top->is_unknown_field) {
13708 return true;
13709 }
13710
Bo Yange3ee7162018-08-10 18:09:02 +000013711 if (!parser_putbool(p, val)) {
13712 return false;
13713 }
13714
Paul Yang9bda1f12018-09-22 18:57:43 -070013715 if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
Bo Yange3ee7162018-08-10 18:09:02 +000013716 end_wrapper_object(p);
13717 if (!is_top_level(p)) {
13718 end_subobject(p);
13719 }
Paul Yang9bda1f12018-09-22 18:57:43 -070013720 return true;
13721 }
13722
13723 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13724 end_value_object(p);
13725 if (!is_top_level(p)) {
13726 end_subobject(p);
13727 }
13728 return true;
13729 }
13730
13731 return true;
13732}
13733
13734static bool end_null(upb_json_parser *p) {
13735 const char *zero_ptr = "0";
13736
13737 if (is_top_level(p)) {
13738 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13739 start_value_object(p, VALUE_NULLVALUE);
13740 } else {
13741 return true;
13742 }
13743 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
13744 if (!start_subobject(p)) {
13745 return false;
13746 }
13747 start_value_object(p, VALUE_NULLVALUE);
13748 } else {
13749 return true;
13750 }
13751
13752 /* Fill null_value field. */
13753 multipart_startaccum(p);
13754 capture_begin(p, zero_ptr);
13755 capture_end(p, zero_ptr + 1);
13756 parse_number(p, false);
13757
13758 end_value_object(p);
13759 if (!is_top_level(p)) {
13760 end_subobject(p);
Bo Yange3ee7162018-08-10 18:09:02 +000013761 }
13762
13763 return true;
13764}
13765
Paul Yang8faa7782018-12-26 10:36:09 -080013766static bool start_any_stringval(upb_json_parser *p) {
13767 multipart_startaccum(p);
13768 return true;
13769}
13770
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013771static bool start_stringval(upb_json_parser *p) {
Bo Yange3ee7162018-08-10 18:09:02 +000013772 if (is_top_level(p)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070013773 if (is_string_wrapper_object(p)) {
13774 start_wrapper_object(p);
Paul Yangc4f2a922019-01-17 10:18:43 -080013775 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) {
13776 start_fieldmask_object(p);
13777 return true;
Paul Yang9bda1f12018-09-22 18:57:43 -070013778 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
13779 is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
13780 start_object(p);
13781 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
13782 start_value_object(p, VALUE_STRINGVALUE);
13783 } else {
Bo Yange3ee7162018-08-10 18:09:02 +000013784 return false;
13785 }
Bo Yange3ee7162018-08-10 18:09:02 +000013786 } else if (does_string_wrapper_start(p)) {
13787 if (!start_subobject(p)) {
13788 return false;
13789 }
13790 start_wrapper_object(p);
Paul Yangc4f2a922019-01-17 10:18:43 -080013791 } else if (does_fieldmask_start(p)) {
13792 if (!start_subobject(p)) {
13793 return false;
13794 }
13795 start_fieldmask_object(p);
13796 return true;
Paul Yang9bda1f12018-09-22 18:57:43 -070013797 } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) ||
13798 is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) {
13799 if (!start_subobject(p)) {
13800 return false;
13801 }
13802 start_object(p);
13803 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
13804 if (!start_subobject(p)) {
13805 return false;
13806 }
13807 start_value_object(p, VALUE_STRINGVALUE);
Bo Yange3ee7162018-08-10 18:09:02 +000013808 }
13809
Paul Yang26eeec92018-07-09 14:29:23 -070013810 if (p->top->f == NULL) {
13811 multipart_startaccum(p);
13812 return true;
13813 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013814
Paul Yang8faa7782018-12-26 10:36:09 -080013815 if (p->top->is_any) {
13816 return start_any_stringval(p);
13817 }
13818
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013819 if (upb_fielddef_isstring(p->top->f)) {
13820 upb_jsonparser_frame *inner;
13821 upb_selector_t sel;
13822
13823 if (!check_stack(p)) return false;
13824
13825 /* Start a new parser frame: parser frames correspond one-to-one with
13826 * handler frames, and string events occur in a sub-frame. */
13827 inner = p->top + 1;
13828 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
13829 upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
13830 inner->m = p->top->m;
13831 inner->f = p->top->f;
Paul Yange0e54662016-09-15 11:09:01 -070013832 inner->name_table = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070013833 inner->is_repeated = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013834 inner->is_map = false;
13835 inner->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080013836 inner->is_any = false;
13837 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070013838 inner->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013839 p->top = inner;
13840
13841 if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
13842 /* For STRING fields we push data directly to the handlers as it is
13843 * parsed. We don't do this yet for BYTES fields, because our base64
13844 * decoder is not streaming.
13845 *
13846 * TODO(haberman): make base64 decoding streaming also. */
13847 multipart_start(p, getsel_for_handlertype(p, UPB_HANDLER_STRING));
13848 return true;
13849 } else {
13850 multipart_startaccum(p);
13851 return true;
13852 }
Paul Yang60327462017-10-09 12:39:13 -070013853 } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
13854 upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
13855 /* No need to push a frame -- numeric values in quotes remain in the
13856 * current parser frame. These values must accmulate so we can convert
13857 * them all at once at the end. */
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013858 multipart_startaccum(p);
13859 return true;
13860 } else {
13861 upb_status_seterrf(&p->status,
Paul Yang60327462017-10-09 12:39:13 -070013862 "String specified for bool or submessage field: %s",
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013863 upb_fielddef_name(p->top->f));
13864 upb_env_reporterror(p->env, &p->status);
13865 return false;
13866 }
13867}
13868
Paul Yang8faa7782018-12-26 10:36:09 -080013869static bool end_any_stringval(upb_json_parser *p) {
13870 size_t len;
13871 const char *buf = accumulate_getptr(p, &len);
13872
13873 /* Set type_url */
13874 upb_selector_t sel;
13875 upb_jsonparser_frame *inner;
13876 if (!check_stack(p)) return false;
13877 inner = p->top + 1;
13878
13879 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
13880 upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
13881 sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
13882 upb_sink_putstring(&inner->sink, sel, buf, len, NULL);
13883 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
13884 upb_sink_endstr(&inner->sink, sel);
13885
13886 multipart_end(p);
13887
13888 /* Resolve type url */
13889 if (strncmp(buf, "type.googleapis.com/", 20) == 0 && len > 20) {
13890 const upb_msgdef *payload_type = NULL;
13891 buf += 20;
13892 len -= 20;
13893
13894 payload_type = upb_symtab_lookupmsg2(p->symtab, buf, len);
13895 if (payload_type == NULL) {
13896 upb_status_seterrf(
13897 &p->status, "Cannot find packed type: %.*s\n", (int)len, buf);
13898 upb_env_reporterror(p->env, &p->status);
13899 return false;
13900 }
13901
13902 json_parser_any_frame_set_payload_type(p, p->top->any_frame, payload_type);
13903
13904 return true;
13905 } else {
13906 upb_status_seterrf(
13907 &p->status, "Invalid type url: %.*s\n", (int)len, buf);
13908 upb_env_reporterror(p->env, &p->status);
13909 return false;
13910 }
13911}
13912
Bo Yange3ee7162018-08-10 18:09:02 +000013913static bool end_stringval_nontop(upb_json_parser *p) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013914 bool ok = true;
13915
Paul Yang9bda1f12018-09-22 18:57:43 -070013916 if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
13917 is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
13918 multipart_end(p);
13919 return true;
13920 }
13921
Paul Yang26eeec92018-07-09 14:29:23 -070013922 if (p->top->f == NULL) {
13923 multipart_end(p);
13924 return true;
13925 }
13926
Paul Yang8faa7782018-12-26 10:36:09 -080013927 if (p->top->is_any) {
13928 return end_any_stringval(p);
13929 }
13930
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013931 switch (upb_fielddef_type(p->top->f)) {
13932 case UPB_TYPE_BYTES:
13933 if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
13934 p->accumulated, p->accumulated_len)) {
13935 return false;
13936 }
13937 /* Fall through. */
13938
13939 case UPB_TYPE_STRING: {
13940 upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
Paul Yange0e54662016-09-15 11:09:01 -070013941 upb_sink_endstr(&p->top->sink, sel);
Paul Yangc4f2a922019-01-17 10:18:43 -080013942 p->top--;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013943 break;
13944 }
13945
13946 case UPB_TYPE_ENUM: {
13947 /* Resolve enum symbolic name to integer value. */
13948 const upb_enumdef *enumdef =
13949 (const upb_enumdef*)upb_fielddef_subdef(p->top->f);
13950
13951 size_t len;
13952 const char *buf = accumulate_getptr(p, &len);
13953
13954 int32_t int_val = 0;
13955 ok = upb_enumdef_ntoi(enumdef, buf, len, &int_val);
13956
13957 if (ok) {
13958 upb_selector_t sel = parser_getsel(p);
13959 upb_sink_putint32(&p->top->sink, sel, int_val);
13960 } else {
13961 upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf);
13962 upb_env_reporterror(p->env, &p->status);
13963 }
13964
13965 break;
13966 }
13967
Paul Yang60327462017-10-09 12:39:13 -070013968 case UPB_TYPE_INT32:
13969 case UPB_TYPE_INT64:
13970 case UPB_TYPE_UINT32:
13971 case UPB_TYPE_UINT64:
13972 case UPB_TYPE_DOUBLE:
13973 case UPB_TYPE_FLOAT:
13974 ok = parse_number(p, true);
13975 break;
13976
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013977 default:
Paul Yange0e54662016-09-15 11:09:01 -070013978 UPB_ASSERT(false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070013979 upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
13980 upb_env_reporterror(p->env, &p->status);
13981 ok = false;
13982 break;
13983 }
13984
13985 multipart_end(p);
13986
13987 return ok;
13988}
13989
Bo Yange3ee7162018-08-10 18:09:02 +000013990static bool end_stringval(upb_json_parser *p) {
Paul Yangc4f2a922019-01-17 10:18:43 -080013991 /* FieldMask's stringvals have been ended when handling them. Only need to
13992 * close FieldMask here.*/
13993 if (does_fieldmask_end(p)) {
13994 end_fieldmask_object(p);
13995 if (!is_top_level(p)) {
13996 end_subobject(p);
13997 }
13998 return true;
13999 }
14000
Bo Yange3ee7162018-08-10 18:09:02 +000014001 if (!end_stringval_nontop(p)) {
14002 return false;
14003 }
14004
14005 if (does_string_wrapper_end(p)) {
14006 end_wrapper_object(p);
14007 if (!is_top_level(p)) {
14008 end_subobject(p);
14009 }
Paul Yang9bda1f12018-09-22 18:57:43 -070014010 return true;
Bo Yange3ee7162018-08-10 18:09:02 +000014011 }
14012
Paul Yang9bda1f12018-09-22 18:57:43 -070014013 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
14014 end_value_object(p);
14015 if (!is_top_level(p)) {
14016 end_subobject(p);
14017 }
14018 return true;
14019 }
14020
14021 if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
Paul Yangc4f2a922019-01-17 10:18:43 -080014022 is_wellknown_msg(p, UPB_WELLKNOWN_DURATION) ||
14023 is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070014024 end_object(p);
14025 if (!is_top_level(p)) {
14026 end_subobject(p);
14027 }
14028 return true;
14029 }
14030
14031 return true;
14032}
14033
14034static void start_duration_base(upb_json_parser *p, const char *ptr) {
14035 capture_begin(p, ptr);
14036}
14037
14038static bool end_duration_base(upb_json_parser *p, const char *ptr) {
14039 size_t len;
14040 const char *buf;
14041 char seconds_buf[14];
14042 char nanos_buf[12];
14043 char *end;
14044 int64_t seconds = 0;
14045 int32_t nanos = 0;
14046 double val = 0.0;
14047 const char *seconds_membername = "seconds";
14048 const char *nanos_membername = "nanos";
14049 size_t fraction_start;
14050
14051 if (!capture_end(p, ptr)) {
14052 return false;
14053 }
14054
14055 buf = accumulate_getptr(p, &len);
14056
14057 memset(seconds_buf, 0, 14);
14058 memset(nanos_buf, 0, 12);
14059
14060 /* Find out base end. The maximus duration is 315576000000, which cannot be
14061 * represented by double without losing precision. Thus, we need to handle
14062 * fraction and base separately. */
14063 for (fraction_start = 0; fraction_start < len && buf[fraction_start] != '.';
14064 fraction_start++);
14065
14066 /* Parse base */
14067 memcpy(seconds_buf, buf, fraction_start);
14068 seconds = strtol(seconds_buf, &end, 10);
14069 if (errno == ERANGE || end != seconds_buf + fraction_start) {
14070 upb_status_seterrf(&p->status, "error parsing duration: %s",
14071 seconds_buf);
14072 upb_env_reporterror(p->env, &p->status);
14073 return false;
14074 }
14075
14076 if (seconds > 315576000000) {
14077 upb_status_seterrf(&p->status, "error parsing duration: "
14078 "maximum acceptable value is "
14079 "315576000000");
14080 upb_env_reporterror(p->env, &p->status);
14081 return false;
14082 }
14083
14084 if (seconds < -315576000000) {
14085 upb_status_seterrf(&p->status, "error parsing duration: "
14086 "minimum acceptable value is "
14087 "-315576000000");
14088 upb_env_reporterror(p->env, &p->status);
14089 return false;
14090 }
14091
14092 /* Parse fraction */
14093 nanos_buf[0] = '0';
14094 memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start);
14095 val = strtod(nanos_buf, &end);
14096 if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) {
14097 upb_status_seterrf(&p->status, "error parsing duration: %s",
14098 nanos_buf);
14099 upb_env_reporterror(p->env, &p->status);
14100 return false;
14101 }
14102
14103 nanos = val * 1000000000;
14104 if (seconds < 0) nanos = -nanos;
14105
14106 /* Clean up buffer */
14107 multipart_end(p);
14108
14109 /* Set seconds */
14110 start_member(p);
14111 capture_begin(p, seconds_membername);
14112 capture_end(p, seconds_membername + 7);
14113 end_membername(p);
14114 upb_sink_putint64(&p->top->sink, parser_getsel(p), seconds);
14115 end_member(p);
14116
14117 /* Set nanos */
14118 start_member(p);
14119 capture_begin(p, nanos_membername);
14120 capture_end(p, nanos_membername + 5);
14121 end_membername(p);
14122 upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos);
14123 end_member(p);
14124
14125 /* Continue previous environment */
14126 multipart_startaccum(p);
14127
14128 return true;
14129}
14130
Paul Yang57b65972019-03-19 22:27:13 -070014131static int parse_timestamp_number(upb_json_parser *p) {
Paul Yang9bda1f12018-09-22 18:57:43 -070014132 size_t len;
14133 const char *buf;
Paul Yang57b65972019-03-19 22:27:13 -070014134 char *end;
14135 int val;
Paul Yang9bda1f12018-09-22 18:57:43 -070014136
Paul Yang57b65972019-03-19 22:27:13 -070014137 /* atoi() and friends unfortunately do not support specifying the length of
14138 * the input string, so we need to force a copy into a NULL-terminated buffer. */
14139 multipart_text(p, "\0", 1, false);
Paul Yang9bda1f12018-09-22 18:57:43 -070014140
14141 buf = accumulate_getptr(p, &len);
Paul Yang57b65972019-03-19 22:27:13 -070014142 val = atoi(buf);
Paul Yang9bda1f12018-09-22 18:57:43 -070014143 multipart_end(p);
14144 multipart_startaccum(p);
14145
Paul Yang57b65972019-03-19 22:27:13 -070014146 return val;
14147}
14148
14149static void start_year(upb_json_parser *p, const char *ptr) {
14150 capture_begin(p, ptr);
14151}
14152
14153static bool end_year(upb_json_parser *p, const char *ptr) {
14154 if (!capture_end(p, ptr)) {
14155 return false;
14156 }
14157 p->tm.tm_year = parse_timestamp_number(p) - 1900;
Paul Yang9bda1f12018-09-22 18:57:43 -070014158 return true;
14159}
14160
Paul Yang57b65972019-03-19 22:27:13 -070014161static void start_month(upb_json_parser *p, const char *ptr) {
14162 capture_begin(p, ptr);
14163}
14164
14165static bool end_month(upb_json_parser *p, const char *ptr) {
14166 if (!capture_end(p, ptr)) {
14167 return false;
14168 }
14169 p->tm.tm_mon = parse_timestamp_number(p) - 1;
14170 return true;
14171}
14172
14173static void start_day(upb_json_parser *p, const char *ptr) {
14174 capture_begin(p, ptr);
14175}
14176
14177static bool end_day(upb_json_parser *p, const char *ptr) {
14178 if (!capture_end(p, ptr)) {
14179 return false;
14180 }
14181 p->tm.tm_mday = parse_timestamp_number(p);
14182 return true;
14183}
14184
14185static void start_hour(upb_json_parser *p, const char *ptr) {
14186 capture_begin(p, ptr);
14187}
14188
14189static bool end_hour(upb_json_parser *p, const char *ptr) {
14190 if (!capture_end(p, ptr)) {
14191 return false;
14192 }
14193 p->tm.tm_hour = parse_timestamp_number(p);
14194 return true;
14195}
14196
14197static void start_minute(upb_json_parser *p, const char *ptr) {
14198 capture_begin(p, ptr);
14199}
14200
14201static bool end_minute(upb_json_parser *p, const char *ptr) {
14202 if (!capture_end(p, ptr)) {
14203 return false;
14204 }
14205 p->tm.tm_min = parse_timestamp_number(p);
14206 return true;
14207}
14208
14209static void start_second(upb_json_parser *p, const char *ptr) {
14210 capture_begin(p, ptr);
14211}
14212
14213static bool end_second(upb_json_parser *p, const char *ptr) {
14214 if (!capture_end(p, ptr)) {
14215 return false;
14216 }
14217 p->tm.tm_sec = parse_timestamp_number(p);
14218 return true;
14219}
14220
14221static void start_timestamp_base(upb_json_parser *p) {
14222 memset(&p->tm, 0, sizeof(struct tm));
14223}
14224
Paul Yang9bda1f12018-09-22 18:57:43 -070014225static void start_timestamp_fraction(upb_json_parser *p, const char *ptr) {
14226 capture_begin(p, ptr);
14227}
14228
14229static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) {
14230 size_t len;
14231 const char *buf;
14232 char nanos_buf[12];
14233 char *end;
14234 double val = 0.0;
14235 int32_t nanos;
14236 const char *nanos_membername = "nanos";
14237
14238 memset(nanos_buf, 0, 12);
14239
14240 if (!capture_end(p, ptr)) {
14241 return false;
14242 }
14243
14244 buf = accumulate_getptr(p, &len);
14245
14246 if (len > 10) {
14247 upb_status_seterrf(&p->status,
14248 "error parsing timestamp: at most 9-digit fraction.");
14249 upb_env_reporterror(p->env, &p->status);
14250 return false;
14251 }
14252
14253 /* Parse nanos */
14254 nanos_buf[0] = '0';
14255 memcpy(nanos_buf + 1, buf, len);
14256 val = strtod(nanos_buf, &end);
14257
14258 if (errno == ERANGE || end != nanos_buf + len + 1) {
14259 upb_status_seterrf(&p->status, "error parsing timestamp nanos: %s",
14260 nanos_buf);
14261 upb_env_reporterror(p->env, &p->status);
14262 return false;
14263 }
14264
14265 nanos = val * 1000000000;
14266
14267 /* Clean up previous environment */
14268 multipart_end(p);
14269
14270 /* Set nanos */
14271 start_member(p);
14272 capture_begin(p, nanos_membername);
14273 capture_end(p, nanos_membername + 5);
14274 end_membername(p);
14275 upb_sink_putint32(&p->top->sink, parser_getsel(p), nanos);
14276 end_member(p);
14277
14278 /* Continue previous environment */
14279 multipart_startaccum(p);
14280
14281 return true;
14282}
14283
14284static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
14285 capture_begin(p, ptr);
14286}
14287
14288static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
14289 size_t len;
14290 const char *buf;
Paul Yang57b65972019-03-19 22:27:13 -070014291 int hours = 0;
Paul Yang9bda1f12018-09-22 18:57:43 -070014292 int64_t seconds;
14293 const char *seconds_membername = "seconds";
14294
14295 if (!capture_end(p, ptr)) {
14296 return false;
14297 }
14298
14299 buf = accumulate_getptr(p, &len);
14300
14301 if (buf[0] != 'Z') {
14302 if (sscanf(buf + 1, "%2d:00", &hours) != 1) {
14303 upb_status_seterrf(&p->status, "error parsing timestamp offset");
14304 upb_env_reporterror(p->env, &p->status);
14305 return false;
14306 }
14307
14308 if (buf[0] == '+') {
14309 hours = -hours;
14310 }
Paul Yang9bda1f12018-09-22 18:57:43 -070014311 }
14312
14313 /* Normalize tm */
Paul Yang57b65972019-03-19 22:27:13 -070014314 seconds = mktime(&p->tm) - timezone;
14315 seconds += 3600 * hours;
Paul Yang9bda1f12018-09-22 18:57:43 -070014316
14317 /* Check timestamp boundary */
14318 if (seconds < -62135596800) {
14319 upb_status_seterrf(&p->status, "error parsing timestamp: "
14320 "minimum acceptable value is "
14321 "0001-01-01T00:00:00Z");
14322 upb_env_reporterror(p->env, &p->status);
14323 return false;
14324 }
14325
14326 /* Clean up previous environment */
14327 multipart_end(p);
14328
14329 /* Set seconds */
14330 start_member(p);
14331 capture_begin(p, seconds_membername);
14332 capture_end(p, seconds_membername + 7);
14333 end_membername(p);
14334 upb_sink_putint64(&p->top->sink, parser_getsel(p), seconds);
14335 end_member(p);
14336
14337 /* Continue previous environment */
14338 multipart_startaccum(p);
14339
Bo Yange3ee7162018-08-10 18:09:02 +000014340 return true;
14341}
14342
Paul Yangc4f2a922019-01-17 10:18:43 -080014343static void start_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
14344 capture_begin(p, ptr);
14345}
14346
14347static bool end_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
14348 if (!capture_end(p, ptr)) {
14349 return false;
14350 }
14351}
14352
14353static bool start_fieldmask_path(upb_json_parser *p) {
14354 upb_jsonparser_frame *inner;
14355 upb_selector_t sel;
14356
14357 if (!check_stack(p)) return false;
14358
14359 /* Start a new parser frame: parser frames correspond one-to-one with
14360 * handler frames, and string events occur in a sub-frame. */
14361 inner = p->top + 1;
14362 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
14363 upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
14364 inner->m = p->top->m;
14365 inner->f = p->top->f;
14366 inner->name_table = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070014367 inner->is_repeated = false;
Paul Yangc4f2a922019-01-17 10:18:43 -080014368 inner->is_map = false;
14369 inner->is_mapentry = false;
14370 inner->is_any = false;
14371 inner->any_frame = NULL;
14372 inner->is_unknown_field = false;
14373 p->top = inner;
14374
14375 multipart_startaccum(p);
14376 return true;
14377}
14378
14379static bool lower_camel_push(
14380 upb_json_parser *p, upb_selector_t sel, const char *ptr, size_t len) {
14381 const char *limit = ptr + len;
14382 bool first = true;
14383 for (;ptr < limit; ptr++) {
14384 if (*ptr >= 'A' && *ptr <= 'Z' && !first) {
14385 char lower = tolower(*ptr);
14386 upb_sink_putstring(&p->top->sink, sel, "_", 1, NULL);
14387 upb_sink_putstring(&p->top->sink, sel, &lower, 1, NULL);
14388 } else {
14389 upb_sink_putstring(&p->top->sink, sel, ptr, 1, NULL);
14390 }
14391 first = false;
14392 }
14393 return true;
14394}
14395
14396static bool end_fieldmask_path(upb_json_parser *p) {
14397 upb_selector_t sel;
14398
14399 if (!lower_camel_push(
14400 p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
14401 p->accumulated, p->accumulated_len)) {
14402 return false;
14403 }
14404
14405 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
14406 upb_sink_endstr(&p->top->sink, sel);
14407 p->top--;
14408
14409 multipart_end(p);
14410 return true;
14411}
14412
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014413static void start_member(upb_json_parser *p) {
Paul Yange0e54662016-09-15 11:09:01 -070014414 UPB_ASSERT(!p->top->f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014415 multipart_startaccum(p);
14416}
14417
14418/* Helper: invoked during parse_mapentry() to emit the mapentry message's key
14419 * field based on the current contents of the accumulate buffer. */
14420static bool parse_mapentry_key(upb_json_parser *p) {
14421
14422 size_t len;
14423 const char *buf = accumulate_getptr(p, &len);
14424
14425 /* Emit the key field. We do a bit of ad-hoc parsing here because the
14426 * parser state machine has already decided that this is a string field
14427 * name, and we are reinterpreting it as some arbitrary key type. In
14428 * particular, integer and bool keys are quoted, so we need to parse the
14429 * quoted string contents here. */
14430
14431 p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
14432 if (p->top->f == NULL) {
14433 upb_status_seterrmsg(&p->status, "mapentry message has no key");
14434 upb_env_reporterror(p->env, &p->status);
14435 return false;
14436 }
14437 switch (upb_fielddef_type(p->top->f)) {
14438 case UPB_TYPE_INT32:
14439 case UPB_TYPE_INT64:
14440 case UPB_TYPE_UINT32:
14441 case UPB_TYPE_UINT64:
14442 /* Invoke end_number. The accum buffer has the number's text already. */
Paul Yang60327462017-10-09 12:39:13 -070014443 if (!parse_number(p, true)) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014444 return false;
14445 }
14446 break;
14447 case UPB_TYPE_BOOL:
14448 if (len == 4 && !strncmp(buf, "true", 4)) {
14449 if (!parser_putbool(p, true)) {
14450 return false;
14451 }
14452 } else if (len == 5 && !strncmp(buf, "false", 5)) {
14453 if (!parser_putbool(p, false)) {
14454 return false;
14455 }
14456 } else {
14457 upb_status_seterrmsg(&p->status,
14458 "Map bool key not 'true' or 'false'");
14459 upb_env_reporterror(p->env, &p->status);
14460 return false;
14461 }
14462 multipart_end(p);
14463 break;
14464 case UPB_TYPE_STRING:
14465 case UPB_TYPE_BYTES: {
14466 upb_sink subsink;
14467 upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
14468 upb_sink_startstr(&p->top->sink, sel, len, &subsink);
14469 sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
14470 upb_sink_putstring(&subsink, sel, buf, len, NULL);
14471 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
Paul Yangc4f2a922019-01-17 10:18:43 -080014472 upb_sink_endstr(&subsink, sel);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014473 multipart_end(p);
14474 break;
14475 }
14476 default:
14477 upb_status_seterrmsg(&p->status, "Invalid field type for map key");
14478 upb_env_reporterror(p->env, &p->status);
14479 return false;
14480 }
14481
14482 return true;
14483}
14484
14485/* Helper: emit one map entry (as a submessage in the map field sequence). This
14486 * is invoked from end_membername(), at the end of the map entry's key string,
14487 * with the map key in the accumulate buffer. It parses the key from that
14488 * buffer, emits the handler calls to start the mapentry submessage (setting up
14489 * its subframe in the process), and sets up state in the subframe so that the
14490 * value parser (invoked next) will emit the mapentry's value field and then
14491 * end the mapentry message. */
14492
14493static bool handle_mapentry(upb_json_parser *p) {
14494 const upb_fielddef *mapfield;
14495 const upb_msgdef *mapentrymsg;
14496 upb_jsonparser_frame *inner;
14497 upb_selector_t sel;
14498
14499 /* Map entry: p->top->sink is the seq frame, so we need to start a frame
14500 * for the mapentry itself, and then set |f| in that frame so that the map
14501 * value field is parsed, and also set a flag to end the frame after the
14502 * map-entry value is parsed. */
14503 if (!check_stack(p)) return false;
14504
14505 mapfield = p->top->mapfield;
14506 mapentrymsg = upb_fielddef_msgsubdef(mapfield);
14507
14508 inner = p->top + 1;
14509 p->top->f = mapfield;
14510 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
14511 upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
14512 inner->m = mapentrymsg;
Paul Yange0e54662016-09-15 11:09:01 -070014513 inner->name_table = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014514 inner->mapfield = mapfield;
Paul Yang4b145b12019-03-12 10:56:58 -070014515 inner->is_repeated = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014516 inner->is_map = false;
Paul Yang8faa7782018-12-26 10:36:09 -080014517 inner->is_any = false;
14518 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014519 inner->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014520
14521 /* Don't set this to true *yet* -- we reuse parsing handlers below to push
14522 * the key field value to the sink, and these handlers will pop the frame
14523 * if they see is_mapentry (when invoked by the parser state machine, they
14524 * would have just seen the map-entry value, not key). */
14525 inner->is_mapentry = false;
14526 p->top = inner;
14527
14528 /* send STARTMSG in submsg frame. */
14529 upb_sink_startmsg(&p->top->sink);
14530
14531 parse_mapentry_key(p);
14532
14533 /* Set up the value field to receive the map-entry value. */
14534 p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
14535 p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */
14536 p->top->mapfield = mapfield;
14537 if (p->top->f == NULL) {
14538 upb_status_seterrmsg(&p->status, "mapentry message has no value");
14539 upb_env_reporterror(p->env, &p->status);
14540 return false;
14541 }
14542
14543 return true;
14544}
14545
14546static bool end_membername(upb_json_parser *p) {
Paul Yange0e54662016-09-15 11:09:01 -070014547 UPB_ASSERT(!p->top->f);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014548
Paul Yang26eeec92018-07-09 14:29:23 -070014549 if (!p->top->m) {
Paul Yangd2d4b402018-10-12 13:46:26 -070014550 p->top->is_unknown_field = true;
14551 multipart_end(p);
Paul Yang26eeec92018-07-09 14:29:23 -070014552 return true;
14553 }
14554
Paul Yang8faa7782018-12-26 10:36:09 -080014555 if (p->top->is_any) {
14556 return end_any_membername(p);
14557 } else if (p->top->is_map) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014558 return handle_mapentry(p);
14559 } else {
14560 size_t len;
14561 const char *buf = accumulate_getptr(p, &len);
Paul Yange0e54662016-09-15 11:09:01 -070014562 upb_value v;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014563
Paul Yange0e54662016-09-15 11:09:01 -070014564 if (upb_strtable_lookup2(p->top->name_table, buf, len, &v)) {
14565 p->top->f = upb_value_getconstptr(v);
14566 multipart_end(p);
14567
14568 return true;
Paul Yang26eeec92018-07-09 14:29:23 -070014569 } else if (p->ignore_json_unknown) {
Paul Yangd2d4b402018-10-12 13:46:26 -070014570 p->top->is_unknown_field = true;
Paul Yang26eeec92018-07-09 14:29:23 -070014571 multipart_end(p);
14572 return true;
Paul Yange0e54662016-09-15 11:09:01 -070014573 } else {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014574 upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
14575 upb_env_reporterror(p->env, &p->status);
14576 return false;
14577 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014578 }
14579}
14580
Paul Yang8faa7782018-12-26 10:36:09 -080014581static bool end_any_membername(upb_json_parser *p) {
14582 size_t len;
14583 const char *buf = accumulate_getptr(p, &len);
14584 upb_value v;
14585
14586 if (len == 5 && strncmp(buf, "@type", len) == 0) {
14587 upb_strtable_lookup2(p->top->name_table, "type_url", 8, &v);
14588 p->top->f = upb_value_getconstptr(v);
14589 multipart_end(p);
14590 return true;
14591 } else {
14592 p->top->is_unknown_field = true;
14593 multipart_end(p);
14594 return true;
14595 }
14596}
14597
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014598static void end_member(upb_json_parser *p) {
14599 /* If we just parsed a map-entry value, end that frame too. */
14600 if (p->top->is_mapentry) {
14601 upb_status s = UPB_STATUS_INIT;
14602 upb_selector_t sel;
14603 bool ok;
14604 const upb_fielddef *mapfield;
14605
Paul Yange0e54662016-09-15 11:09:01 -070014606 UPB_ASSERT(p->top > p->stack);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014607 /* send ENDMSG on submsg. */
14608 upb_sink_endmsg(&p->top->sink, &s);
14609 mapfield = p->top->mapfield;
14610
14611 /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
14612 p->top--;
14613 ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
Paul Yange0e54662016-09-15 11:09:01 -070014614 UPB_ASSERT(ok);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014615 upb_sink_endsubmsg(&p->top->sink, sel);
14616 }
14617
14618 p->top->f = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014619 p->top->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014620}
14621
Paul Yang8faa7782018-12-26 10:36:09 -080014622static void start_any_member(upb_json_parser *p, const char *ptr) {
14623 start_member(p);
14624 json_parser_any_frame_set_after_type_url_start_once(p->top->any_frame, ptr);
14625}
14626
14627static void end_any_member(upb_json_parser *p, const char *ptr) {
14628 json_parser_any_frame_set_before_type_url_end(p->top->any_frame, ptr);
14629 end_member(p);
14630}
14631
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014632static bool start_subobject(upb_json_parser *p) {
Paul Yangd2d4b402018-10-12 13:46:26 -070014633 if (p->top->is_unknown_field) {
Paul Yang26eeec92018-07-09 14:29:23 -070014634 upb_jsonparser_frame *inner;
14635 if (!check_stack(p)) return false;
14636
14637 inner = p->top + 1;
14638 inner->m = NULL;
14639 inner->f = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070014640 inner->is_repeated = false;
Paul Yang26eeec92018-07-09 14:29:23 -070014641 inner->is_map = false;
14642 inner->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080014643 inner->is_any = false;
14644 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014645 inner->is_unknown_field = false;
Paul Yang26eeec92018-07-09 14:29:23 -070014646 p->top = inner;
14647 return true;
14648 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014649
14650 if (upb_fielddef_ismap(p->top->f)) {
14651 upb_jsonparser_frame *inner;
14652 upb_selector_t sel;
14653
14654 /* Beginning of a map. Start a new parser frame in a repeated-field
14655 * context. */
14656 if (!check_stack(p)) return false;
14657
14658 inner = p->top + 1;
14659 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
14660 upb_sink_startseq(&p->top->sink, sel, &inner->sink);
14661 inner->m = upb_fielddef_msgsubdef(p->top->f);
Paul Yange0e54662016-09-15 11:09:01 -070014662 inner->name_table = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014663 inner->mapfield = p->top->f;
14664 inner->f = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070014665 inner->is_repeated = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014666 inner->is_map = true;
14667 inner->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080014668 inner->is_any = false;
14669 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014670 inner->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014671 p->top = inner;
14672
14673 return true;
14674 } else if (upb_fielddef_issubmsg(p->top->f)) {
14675 upb_jsonparser_frame *inner;
14676 upb_selector_t sel;
14677
14678 /* Beginning of a subobject. Start a new parser frame in the submsg
14679 * context. */
14680 if (!check_stack(p)) return false;
14681
14682 inner = p->top + 1;
14683
14684 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
14685 upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
14686 inner->m = upb_fielddef_msgsubdef(p->top->f);
Paul Yange0e54662016-09-15 11:09:01 -070014687 set_name_table(p, inner);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014688 inner->f = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070014689 inner->is_repeated = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014690 inner->is_map = false;
14691 inner->is_mapentry = false;
Paul Yangd2d4b402018-10-12 13:46:26 -070014692 inner->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014693 p->top = inner;
14694
Paul Yang8faa7782018-12-26 10:36:09 -080014695 if (is_wellknown_msg(p, UPB_WELLKNOWN_ANY)) {
14696 p->top->is_any = true;
14697 p->top->any_frame =
14698 upb_env_malloc(p->env, sizeof(upb_jsonparser_any_frame));
14699 json_parser_any_frame_reset(p->top->any_frame);
14700 } else {
14701 p->top->is_any = false;
14702 p->top->any_frame = NULL;
14703 }
14704
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014705 return true;
14706 } else {
14707 upb_status_seterrf(&p->status,
14708 "Object specified for non-message/group field: %s",
14709 upb_fielddef_name(p->top->f));
14710 upb_env_reporterror(p->env, &p->status);
14711 return false;
14712 }
14713}
14714
Paul Yang9bda1f12018-09-22 18:57:43 -070014715static bool start_subobject_full(upb_json_parser *p) {
14716 if (is_top_level(p)) {
14717 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
14718 start_value_object(p, VALUE_STRUCTVALUE);
14719 if (!start_subobject(p)) return false;
14720 start_structvalue_object(p);
14721 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
14722 start_structvalue_object(p);
14723 } else {
14724 return true;
14725 }
14726 } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) {
14727 if (!start_subobject(p)) return false;
14728 start_structvalue_object(p);
14729 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
14730 if (!start_subobject(p)) return false;
14731 start_value_object(p, VALUE_STRUCTVALUE);
14732 if (!start_subobject(p)) return false;
14733 start_structvalue_object(p);
14734 }
14735
14736 return start_subobject(p);
14737}
14738
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014739static void end_subobject(upb_json_parser *p) {
Bo Yange3ee7162018-08-10 18:09:02 +000014740 if (is_top_level(p)) {
14741 return;
14742 }
14743
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014744 if (p->top->is_map) {
14745 upb_selector_t sel;
14746 p->top--;
14747 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
14748 upb_sink_endseq(&p->top->sink, sel);
14749 } else {
14750 upb_selector_t sel;
Paul Yang26eeec92018-07-09 14:29:23 -070014751 bool is_unknown = p->top->m == NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014752 p->top--;
Paul Yang26eeec92018-07-09 14:29:23 -070014753 if (!is_unknown) {
14754 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
14755 upb_sink_endsubmsg(&p->top->sink, sel);
14756 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014757 }
14758}
14759
Paul Yang9bda1f12018-09-22 18:57:43 -070014760static void end_subobject_full(upb_json_parser *p) {
14761 end_subobject(p);
14762
14763 if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
14764 end_structvalue_object(p);
14765 if (!is_top_level(p)) {
14766 end_subobject(p);
14767 }
14768 }
14769
14770 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
14771 end_value_object(p);
14772 if (!is_top_level(p)) {
14773 end_subobject(p);
14774 }
14775 }
14776}
14777
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014778static bool start_array(upb_json_parser *p) {
14779 upb_jsonparser_frame *inner;
14780 upb_selector_t sel;
14781
Paul Yang9bda1f12018-09-22 18:57:43 -070014782 if (is_top_level(p)) {
14783 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
14784 start_value_object(p, VALUE_LISTVALUE);
14785 if (!start_subobject(p)) return false;
14786 start_listvalue_object(p);
14787 } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
14788 start_listvalue_object(p);
14789 } else {
14790 return false;
14791 }
Paul Yang4b145b12019-03-12 10:56:58 -070014792 } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE) &&
14793 (!upb_fielddef_isseq(p->top->f) ||
14794 p->top->is_repeated)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070014795 if (!start_subobject(p)) return false;
14796 start_listvalue_object(p);
Paul Yang4b145b12019-03-12 10:56:58 -070014797 } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE) &&
14798 (!upb_fielddef_isseq(p->top->f) ||
14799 p->top->is_repeated)) {
Paul Yang9bda1f12018-09-22 18:57:43 -070014800 if (!start_subobject(p)) return false;
14801 start_value_object(p, VALUE_LISTVALUE);
14802 if (!start_subobject(p)) return false;
14803 start_listvalue_object(p);
14804 }
14805
Paul Yangd2d4b402018-10-12 13:46:26 -070014806 if (p->top->is_unknown_field) {
14807 inner = p->top + 1;
14808 inner->m = NULL;
14809 inner->name_table = NULL;
14810 inner->f = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070014811 inner->is_repeated = false;
Paul Yangd2d4b402018-10-12 13:46:26 -070014812 inner->is_map = false;
14813 inner->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080014814 inner->is_any = false;
14815 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014816 inner->is_unknown_field = true;
14817 p->top = inner;
14818
14819 return true;
14820 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014821
14822 if (!upb_fielddef_isseq(p->top->f)) {
14823 upb_status_seterrf(&p->status,
14824 "Array specified for non-repeated field: %s",
14825 upb_fielddef_name(p->top->f));
14826 upb_env_reporterror(p->env, &p->status);
14827 return false;
14828 }
14829
14830 if (!check_stack(p)) return false;
14831
14832 inner = p->top + 1;
14833 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
14834 upb_sink_startseq(&p->top->sink, sel, &inner->sink);
14835 inner->m = p->top->m;
Paul Yange0e54662016-09-15 11:09:01 -070014836 inner->name_table = NULL;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014837 inner->f = p->top->f;
Paul Yang4b145b12019-03-12 10:56:58 -070014838 inner->is_repeated = true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014839 inner->is_map = false;
14840 inner->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080014841 inner->is_any = false;
14842 inner->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070014843 inner->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014844 p->top = inner;
14845
14846 return true;
14847}
14848
14849static void end_array(upb_json_parser *p) {
14850 upb_selector_t sel;
14851
Paul Yange0e54662016-09-15 11:09:01 -070014852 UPB_ASSERT(p->top > p->stack);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014853
14854 p->top--;
Paul Yangd2d4b402018-10-12 13:46:26 -070014855
14856 if (p->top->is_unknown_field) {
14857 return;
14858 }
14859
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014860 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
14861 upb_sink_endseq(&p->top->sink, sel);
Paul Yang9bda1f12018-09-22 18:57:43 -070014862
14863 if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
14864 end_listvalue_object(p);
14865 if (!is_top_level(p)) {
14866 end_subobject(p);
14867 }
14868 }
14869
14870 if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
14871 end_value_object(p);
14872 if (!is_top_level(p)) {
14873 end_subobject(p);
14874 }
14875 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014876}
14877
14878static void start_object(upb_json_parser *p) {
Paul Yangd2d4b402018-10-12 13:46:26 -070014879 if (!p->top->is_map && p->top->m != NULL) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014880 upb_sink_startmsg(&p->top->sink);
14881 }
14882}
14883
14884static void end_object(upb_json_parser *p) {
Paul Yangd2d4b402018-10-12 13:46:26 -070014885 if (!p->top->is_map && p->top->m != NULL) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070014886 upb_status status;
14887 upb_status_clear(&status);
14888 upb_sink_endmsg(&p->top->sink, &status);
14889 if (!upb_ok(&status)) {
14890 upb_env_reporterror(p->env, &status);
14891 }
14892 }
14893}
14894
Paul Yang8faa7782018-12-26 10:36:09 -080014895static void start_any_object(upb_json_parser *p, const char *ptr) {
14896 start_object(p);
14897 p->top->any_frame->before_type_url_start = ptr;
14898 p->top->any_frame->before_type_url_end = ptr;
14899}
14900
14901static bool end_any_object(upb_json_parser *p, const char *ptr) {
14902 const char *value_membername = "value";
14903 bool is_well_known_packed = false;
14904 const char *packed_end = ptr + 1;
14905 upb_selector_t sel;
14906 upb_jsonparser_frame *inner;
14907
14908 if (json_parser_any_frame_has_value(p->top->any_frame) &&
14909 !json_parser_any_frame_has_type_url(p->top->any_frame)) {
14910 upb_status_seterrmsg(&p->status, "No valid type url");
14911 upb_env_reporterror(p->env, &p->status);
14912 return false;
14913 }
14914
14915 /* Well known types data is represented as value field. */
14916 if (upb_msgdef_wellknowntype(p->top->any_frame->parser->top->m) !=
14917 UPB_WELLKNOWN_UNSPECIFIED) {
14918 is_well_known_packed = true;
14919
14920 if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
14921 p->top->any_frame->before_type_url_start =
14922 memchr(p->top->any_frame->before_type_url_start, ':',
14923 p->top->any_frame->before_type_url_end -
14924 p->top->any_frame->before_type_url_start);
14925 if (p->top->any_frame->before_type_url_start == NULL) {
14926 upb_status_seterrmsg(&p->status, "invalid data for well known type.");
14927 upb_env_reporterror(p->env, &p->status);
14928 return false;
14929 }
14930 p->top->any_frame->before_type_url_start++;
14931 }
14932
14933 if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
14934 p->top->any_frame->after_type_url_start =
14935 memchr(p->top->any_frame->after_type_url_start, ':',
14936 (ptr + 1) -
14937 p->top->any_frame->after_type_url_start);
14938 if (p->top->any_frame->after_type_url_start == NULL) {
14939 upb_status_seterrmsg(&p->status, "Invalid data for well known type.");
14940 upb_env_reporterror(p->env, &p->status);
14941 return false;
14942 }
14943 p->top->any_frame->after_type_url_start++;
14944 packed_end = ptr;
14945 }
14946 }
14947
14948 if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
14949 if (!parse(p->top->any_frame->parser, NULL,
14950 p->top->any_frame->before_type_url_start,
14951 p->top->any_frame->before_type_url_end -
14952 p->top->any_frame->before_type_url_start, NULL)) {
14953 return false;
14954 }
14955 } else {
14956 if (!is_well_known_packed) {
14957 if (!parse(p->top->any_frame->parser, NULL, "{", 1, NULL)) {
14958 return false;
14959 }
14960 }
14961 }
14962
14963 if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame) &&
14964 json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
14965 if (!parse(p->top->any_frame->parser, NULL, ",", 1, NULL)) {
14966 return false;
14967 }
14968 }
14969
14970 if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
14971 if (!parse(p->top->any_frame->parser, NULL,
14972 p->top->any_frame->after_type_url_start,
14973 packed_end - p->top->any_frame->after_type_url_start, NULL)) {
14974 return false;
14975 }
14976 } else {
14977 if (!is_well_known_packed) {
14978 if (!parse(p->top->any_frame->parser, NULL, "}", 1, NULL)) {
14979 return false;
14980 }
14981 }
14982 }
14983
14984 if (!end(p->top->any_frame->parser, NULL)) {
14985 return false;
14986 }
14987
14988 p->top->is_any = false;
14989
14990 /* Set value */
14991 start_member(p);
14992 capture_begin(p, value_membername);
14993 capture_end(p, value_membername + 5);
14994 end_membername(p);
14995
14996 if (!check_stack(p)) return false;
14997 inner = p->top + 1;
14998
14999 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
15000 upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
15001 sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
15002 upb_sink_putstring(&inner->sink, sel, p->top->any_frame->stringsink.ptr,
15003 p->top->any_frame->stringsink.len, NULL);
15004 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
15005 upb_sink_endstr(&inner->sink, sel);
15006
15007 end_member(p);
15008
15009 end_object(p);
15010
15011 /* Deallocate any parse frame. */
15012 json_parser_any_frame_free(p->top->any_frame);
15013 upb_env_free(p->env, p->top->any_frame);
15014
15015 return true;
15016}
15017
Bo Yange3ee7162018-08-10 18:09:02 +000015018static bool is_string_wrapper(const upb_msgdef *m) {
Paul Yang9bda1f12018-09-22 18:57:43 -070015019 upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
15020 return type == UPB_WELLKNOWN_STRINGVALUE ||
15021 type == UPB_WELLKNOWN_BYTESVALUE;
Bo Yange3ee7162018-08-10 18:09:02 +000015022}
15023
Paul Yangc4f2a922019-01-17 10:18:43 -080015024static bool is_fieldmask(const upb_msgdef *m) {
15025 upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
15026 return type == UPB_WELLKNOWN_FIELDMASK;
15027}
15028
15029static void start_fieldmask_object(upb_json_parser *p) {
15030 const char *membername = "paths";
15031
15032 start_object(p);
15033
15034 /* Set up context for parsing value */
15035 start_member(p);
15036 capture_begin(p, membername);
15037 capture_end(p, membername + 5);
15038 end_membername(p);
15039
15040 start_array(p);
15041}
15042
15043static void end_fieldmask_object(upb_json_parser *p) {
15044 end_array(p);
15045 end_member(p);
15046 end_object(p);
15047}
15048
Bo Yange3ee7162018-08-10 18:09:02 +000015049static void start_wrapper_object(upb_json_parser *p) {
15050 const char *membername = "value";
15051
15052 start_object(p);
15053
15054 /* Set up context for parsing value */
15055 start_member(p);
15056 capture_begin(p, membername);
15057 capture_end(p, membername + 5);
15058 end_membername(p);
15059}
15060
15061static void end_wrapper_object(upb_json_parser *p) {
15062 end_member(p);
15063 end_object(p);
15064}
15065
Paul Yang9bda1f12018-09-22 18:57:43 -070015066static void start_value_object(upb_json_parser *p, int value_type) {
15067 const char *nullmember = "null_value";
15068 const char *numbermember = "number_value";
15069 const char *stringmember = "string_value";
15070 const char *boolmember = "bool_value";
15071 const char *structmember = "struct_value";
15072 const char *listmember = "list_value";
15073 const char *membername = "";
15074
15075 switch (value_type) {
15076 case VALUE_NULLVALUE:
15077 membername = nullmember;
15078 break;
15079 case VALUE_NUMBERVALUE:
15080 membername = numbermember;
15081 break;
15082 case VALUE_STRINGVALUE:
15083 membername = stringmember;
15084 break;
15085 case VALUE_BOOLVALUE:
15086 membername = boolmember;
15087 break;
15088 case VALUE_STRUCTVALUE:
15089 membername = structmember;
15090 break;
15091 case VALUE_LISTVALUE:
15092 membername = listmember;
15093 break;
15094 }
15095
15096 start_object(p);
15097
15098 /* Set up context for parsing value */
15099 start_member(p);
15100 capture_begin(p, membername);
15101 capture_end(p, membername + strlen(membername));
15102 end_membername(p);
15103}
15104
15105static void end_value_object(upb_json_parser *p) {
15106 end_member(p);
15107 end_object(p);
15108}
15109
15110static void start_listvalue_object(upb_json_parser *p) {
15111 const char *membername = "values";
15112
15113 start_object(p);
15114
15115 /* Set up context for parsing value */
15116 start_member(p);
15117 capture_begin(p, membername);
15118 capture_end(p, membername + strlen(membername));
15119 end_membername(p);
15120}
15121
15122static void end_listvalue_object(upb_json_parser *p) {
15123 end_member(p);
15124 end_object(p);
15125}
15126
15127static void start_structvalue_object(upb_json_parser *p) {
15128 const char *membername = "fields";
15129
15130 start_object(p);
15131
15132 /* Set up context for parsing value */
15133 start_member(p);
15134 capture_begin(p, membername);
15135 capture_end(p, membername + strlen(membername));
15136 end_membername(p);
15137}
15138
15139static void end_structvalue_object(upb_json_parser *p) {
15140 end_member(p);
15141 end_object(p);
15142}
15143
Bo Yange3ee7162018-08-10 18:09:02 +000015144static bool is_top_level(upb_json_parser *p) {
Paul Yangd2d4b402018-10-12 13:46:26 -070015145 return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field;
Bo Yange3ee7162018-08-10 18:09:02 +000015146}
15147
Paul Yang9bda1f12018-09-22 18:57:43 -070015148static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) {
15149 return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type;
15150}
15151
15152static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) {
15153 return p->top->f != NULL &&
15154 upb_fielddef_issubmsg(p->top->f) &&
15155 (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f))
15156 == type);
15157}
15158
Bo Yange3ee7162018-08-10 18:09:02 +000015159static bool does_number_wrapper_start(upb_json_parser *p) {
15160 return p->top->f != NULL &&
15161 upb_fielddef_issubmsg(p->top->f) &&
Paul Yang9bda1f12018-09-22 18:57:43 -070015162 upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f));
Bo Yange3ee7162018-08-10 18:09:02 +000015163}
15164
15165static bool does_number_wrapper_end(upb_json_parser *p) {
Paul Yang9bda1f12018-09-22 18:57:43 -070015166 return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
Bo Yange3ee7162018-08-10 18:09:02 +000015167}
15168
15169static bool is_number_wrapper_object(upb_json_parser *p) {
Paul Yang9bda1f12018-09-22 18:57:43 -070015170 return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
Bo Yange3ee7162018-08-10 18:09:02 +000015171}
15172
15173static bool does_string_wrapper_start(upb_json_parser *p) {
15174 return p->top->f != NULL &&
15175 upb_fielddef_issubmsg(p->top->f) &&
15176 is_string_wrapper(upb_fielddef_msgsubdef(p->top->f));
15177}
15178
15179static bool does_string_wrapper_end(upb_json_parser *p) {
15180 return p->top->m != NULL && is_string_wrapper(p->top->m);
15181}
15182
15183static bool is_string_wrapper_object(upb_json_parser *p) {
15184 return p->top->m != NULL && is_string_wrapper(p->top->m);
15185}
15186
Paul Yangc4f2a922019-01-17 10:18:43 -080015187static bool does_fieldmask_start(upb_json_parser *p) {
15188 return p->top->f != NULL &&
15189 upb_fielddef_issubmsg(p->top->f) &&
15190 is_fieldmask(upb_fielddef_msgsubdef(p->top->f));
15191}
15192
15193static bool does_fieldmask_end(upb_json_parser *p) {
15194 return p->top->m != NULL && is_fieldmask(p->top->m);
15195}
15196
15197static bool is_fieldmask_object(upb_json_parser *p) {
15198 return p->top->m != NULL && is_fieldmask(p->top->m);
15199}
15200
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015201#define CHECK_RETURN_TOP(x) if (!(x)) goto error
15202
15203
15204/* The actual parser **********************************************************/
15205
15206/* What follows is the Ragel parser itself. The language is specified in Ragel
15207 * and the actions call our C functions above.
15208 *
15209 * Ragel has an extensive set of functionality, and we use only a small part of
15210 * it. There are many action types but we only use a few:
15211 *
15212 * ">" -- transition into a machine
15213 * "%" -- transition out of a machine
15214 * "@" -- transition into a final state of a machine.
15215 *
15216 * "@" transitions are tricky because a machine can transition into a final
15217 * state repeatedly. But in some cases we know this can't happen, for example
15218 * a string which is delimited by a final '"' can only transition into its
15219 * final state once, when the closing '"' is seen. */
15220
15221
Paul Yang57b65972019-03-19 22:27:13 -070015222#line 2824 "upb/json/parser.rl"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015223
15224
15225
Paul Yang57b65972019-03-19 22:27:13 -070015226#line 2627 "upb/json/parser.c"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015227static const char _json_actions[] = {
Bo Yange3ee7162018-08-10 18:09:02 +000015228 0, 1, 0, 1, 1, 1, 3, 1,
15229 4, 1, 6, 1, 7, 1, 8, 1,
Paul Yang57b65972019-03-19 22:27:13 -070015230 9, 1, 11, 1, 12, 1, 13, 1,
15231 14, 1, 15, 1, 16, 1, 17, 1,
15232 18, 1, 19, 1, 20, 1, 22, 1,
15233 23, 1, 24, 1, 35, 1, 37, 1,
15234 39, 1, 40, 1, 42, 1, 43, 1,
15235 44, 1, 46, 1, 48, 1, 49, 1,
15236 50, 1, 51, 1, 53, 1, 54, 2,
15237 4, 9, 2, 5, 6, 2, 7, 3,
15238 2, 7, 9, 2, 21, 26, 2, 25,
15239 10, 2, 27, 28, 2, 29, 30, 2,
15240 32, 34, 2, 33, 31, 2, 38, 36,
15241 2, 40, 42, 2, 45, 2, 2, 46,
15242 54, 2, 47, 36, 2, 49, 54, 2,
15243 50, 54, 2, 51, 54, 2, 52, 41,
15244 2, 53, 54, 3, 32, 34, 35, 4,
15245 21, 26, 27, 28
Bo Yange3ee7162018-08-10 18:09:02 +000015246};
15247
Paul Yang7f42d6d2019-01-22 15:35:12 -080015248static const short _json_key_offsets[] = {
15249 0, 0, 12, 13, 18, 23, 28, 29,
15250 30, 31, 32, 33, 34, 35, 36, 37,
15251 38, 43, 44, 48, 53, 58, 63, 67,
15252 71, 74, 77, 79, 83, 87, 89, 91,
15253 96, 98, 100, 109, 115, 121, 127, 133,
15254 135, 139, 142, 144, 146, 149, 150, 154,
15255 156, 158, 160, 162, 163, 165, 167, 168,
15256 170, 172, 173, 175, 177, 178, 180, 182,
15257 183, 185, 187, 191, 193, 195, 196, 197,
15258 198, 199, 201, 206, 208, 210, 212, 221,
15259 222, 222, 222, 227, 232, 237, 238, 239,
15260 240, 241, 241, 242, 243, 244, 244, 245,
15261 246, 247, 247, 252, 253, 257, 262, 267,
15262 272, 276, 276, 279, 282, 285, 288, 291,
15263 294, 294, 294, 294, 294, 294
15264};
15265
15266static const char _json_trans_keys[] = {
15267 32, 34, 45, 91, 102, 110, 116, 123,
15268 9, 13, 48, 57, 34, 32, 93, 125,
15269 9, 13, 32, 44, 93, 9, 13, 32,
15270 93, 125, 9, 13, 97, 108, 115, 101,
15271 117, 108, 108, 114, 117, 101, 32, 34,
15272 125, 9, 13, 34, 32, 58, 9, 13,
15273 32, 93, 125, 9, 13, 32, 44, 125,
15274 9, 13, 32, 44, 125, 9, 13, 32,
15275 34, 9, 13, 45, 48, 49, 57, 48,
15276 49, 57, 46, 69, 101, 48, 57, 69,
15277 101, 48, 57, 43, 45, 48, 57, 48,
15278 57, 48, 57, 46, 69, 101, 48, 57,
15279 34, 92, 34, 92, 34, 47, 92, 98,
15280 102, 110, 114, 116, 117, 48, 57, 65,
15281 70, 97, 102, 48, 57, 65, 70, 97,
15282 102, 48, 57, 65, 70, 97, 102, 48,
15283 57, 65, 70, 97, 102, 34, 92, 45,
15284 48, 49, 57, 48, 49, 57, 46, 115,
15285 48, 57, 115, 48, 57, 34, 46, 115,
15286 48, 57, 48, 57, 48, 57, 48, 57,
15287 48, 57, 45, 48, 57, 48, 57, 45,
15288 48, 57, 48, 57, 84, 48, 57, 48,
15289 57, 58, 48, 57, 48, 57, 58, 48,
15290 57, 48, 57, 43, 45, 46, 90, 48,
15291 57, 48, 57, 58, 48, 48, 34, 48,
15292 57, 43, 45, 90, 48, 57, 34, 44,
15293 34, 44, 34, 44, 34, 45, 91, 102,
15294 110, 116, 123, 48, 57, 34, 32, 93,
15295 125, 9, 13, 32, 44, 93, 9, 13,
15296 32, 93, 125, 9, 13, 97, 108, 115,
15297 101, 117, 108, 108, 114, 117, 101, 32,
15298 34, 125, 9, 13, 34, 32, 58, 9,
15299 13, 32, 93, 125, 9, 13, 32, 44,
15300 125, 9, 13, 32, 44, 125, 9, 13,
15301 32, 34, 9, 13, 32, 9, 13, 32,
15302 9, 13, 32, 9, 13, 32, 9, 13,
15303 32, 9, 13, 32, 9, 13, 0
15304};
15305
15306static const char _json_single_lengths[] = {
15307 0, 8, 1, 3, 3, 3, 1, 1,
15308 1, 1, 1, 1, 1, 1, 1, 1,
15309 3, 1, 2, 3, 3, 3, 2, 2,
15310 1, 3, 0, 2, 2, 0, 0, 3,
15311 2, 2, 9, 0, 0, 0, 0, 2,
15312 2, 1, 2, 0, 1, 1, 2, 0,
15313 0, 0, 0, 1, 0, 0, 1, 0,
15314 0, 1, 0, 0, 1, 0, 0, 1,
15315 0, 0, 4, 0, 0, 1, 1, 1,
15316 1, 0, 3, 2, 2, 2, 7, 1,
15317 0, 0, 3, 3, 3, 1, 1, 1,
15318 1, 0, 1, 1, 1, 0, 1, 1,
15319 1, 0, 3, 1, 2, 3, 3, 3,
15320 2, 0, 1, 1, 1, 1, 1, 1,
15321 0, 0, 0, 0, 0, 0
15322};
15323
15324static const char _json_range_lengths[] = {
15325 0, 2, 0, 1, 1, 1, 0, 0,
15326 0, 0, 0, 0, 0, 0, 0, 0,
15327 1, 0, 1, 1, 1, 1, 1, 1,
15328 1, 0, 1, 1, 1, 1, 1, 1,
15329 0, 0, 0, 3, 3, 3, 3, 0,
15330 1, 1, 0, 1, 1, 0, 1, 1,
15331 1, 1, 1, 0, 1, 1, 0, 1,
15332 1, 0, 1, 1, 0, 1, 1, 0,
15333 1, 1, 0, 1, 1, 0, 0, 0,
15334 0, 1, 1, 0, 0, 0, 1, 0,
15335 0, 0, 1, 1, 1, 0, 0, 0,
15336 0, 0, 0, 0, 0, 0, 0, 0,
15337 0, 0, 1, 0, 1, 1, 1, 1,
15338 1, 0, 1, 1, 1, 1, 1, 1,
15339 0, 0, 0, 0, 0, 0
15340};
15341
15342static const short _json_index_offsets[] = {
15343 0, 0, 11, 13, 18, 23, 28, 30,
15344 32, 34, 36, 38, 40, 42, 44, 46,
15345 48, 53, 55, 59, 64, 69, 74, 78,
15346 82, 85, 89, 91, 95, 99, 101, 103,
15347 108, 111, 114, 124, 128, 132, 136, 140,
15348 143, 147, 150, 153, 155, 158, 160, 164,
15349 166, 168, 170, 172, 174, 176, 178, 180,
15350 182, 184, 186, 188, 190, 192, 194, 196,
15351 198, 200, 202, 207, 209, 211, 213, 215,
15352 217, 219, 221, 226, 229, 232, 235, 244,
15353 246, 247, 248, 253, 258, 263, 265, 267,
15354 269, 271, 272, 274, 276, 278, 279, 281,
15355 283, 285, 286, 291, 293, 297, 302, 307,
15356 312, 316, 317, 320, 323, 326, 329, 332,
15357 335, 336, 337, 338, 339, 340
15358};
15359
15360static const unsigned char _json_indicies[] = {
15361 0, 2, 3, 4, 5, 6, 7, 8,
15362 0, 3, 1, 9, 1, 11, 12, 1,
15363 11, 10, 13, 14, 12, 13, 1, 14,
15364 1, 1, 14, 10, 15, 1, 16, 1,
15365 17, 1, 18, 1, 19, 1, 20, 1,
15366 21, 1, 22, 1, 23, 1, 24, 1,
15367 25, 26, 27, 25, 1, 28, 1, 29,
15368 30, 29, 1, 30, 1, 1, 30, 31,
15369 32, 33, 34, 32, 1, 35, 36, 27,
15370 35, 1, 36, 26, 36, 1, 37, 38,
15371 39, 1, 38, 39, 1, 41, 42, 42,
15372 40, 43, 1, 42, 42, 43, 40, 44,
15373 44, 45, 1, 45, 1, 45, 40, 41,
15374 42, 42, 39, 40, 47, 48, 46, 50,
15375 51, 49, 52, 52, 52, 52, 52, 52,
15376 52, 52, 53, 1, 54, 54, 54, 1,
15377 55, 55, 55, 1, 56, 56, 56, 1,
15378 57, 57, 57, 1, 59, 60, 58, 61,
15379 62, 63, 1, 64, 65, 1, 66, 67,
15380 1, 68, 1, 67, 68, 1, 69, 1,
15381 66, 67, 65, 1, 70, 1, 71, 1,
15382 72, 1, 73, 1, 74, 1, 75, 1,
15383 76, 1, 77, 1, 78, 1, 79, 1,
15384 80, 1, 81, 1, 82, 1, 83, 1,
15385 84, 1, 85, 1, 86, 1, 87, 1,
15386 88, 1, 89, 89, 90, 91, 1, 92,
15387 1, 93, 1, 94, 1, 95, 1, 96,
15388 1, 97, 1, 98, 1, 99, 99, 100,
15389 98, 1, 102, 1, 101, 104, 105, 103,
15390 1, 1, 101, 106, 107, 108, 109, 110,
15391 111, 112, 107, 1, 113, 1, 114, 115,
15392 117, 118, 1, 117, 116, 119, 120, 118,
15393 119, 1, 120, 1, 1, 120, 116, 121,
15394 1, 122, 1, 123, 1, 124, 1, 125,
15395 126, 1, 127, 1, 128, 1, 129, 130,
15396 1, 131, 1, 132, 1, 133, 134, 135,
15397 136, 134, 1, 137, 1, 138, 139, 138,
15398 1, 139, 1, 1, 139, 140, 141, 142,
15399 143, 141, 1, 144, 145, 136, 144, 1,
15400 145, 135, 145, 1, 146, 147, 147, 1,
15401 148, 148, 1, 149, 149, 1, 150, 150,
15402 1, 151, 151, 1, 152, 152, 1, 1,
15403 1, 1, 1, 1, 1, 0
15404};
15405
15406static const char _json_trans_targs[] = {
15407 1, 0, 2, 107, 3, 6, 10, 13,
15408 16, 106, 4, 3, 106, 4, 5, 7,
15409 8, 9, 108, 11, 12, 109, 14, 15,
15410 110, 16, 17, 111, 18, 18, 19, 20,
15411 21, 22, 111, 21, 22, 24, 25, 31,
15412 112, 26, 28, 27, 29, 30, 33, 113,
15413 34, 33, 113, 34, 32, 35, 36, 37,
15414 38, 39, 33, 113, 34, 41, 42, 46,
15415 42, 46, 43, 45, 44, 114, 48, 49,
15416 50, 51, 52, 53, 54, 55, 56, 57,
15417 58, 59, 60, 61, 62, 63, 64, 65,
15418 66, 67, 73, 72, 68, 69, 70, 71,
15419 72, 115, 74, 67, 72, 76, 116, 76,
15420 116, 77, 79, 81, 82, 85, 90, 94,
15421 98, 80, 117, 117, 83, 82, 80, 83,
15422 84, 86, 87, 88, 89, 117, 91, 92,
15423 93, 117, 95, 96, 97, 117, 98, 99,
15424 105, 100, 100, 101, 102, 103, 104, 105,
15425 103, 104, 117, 106, 106, 106, 106, 106,
15426 106
15427};
15428
Paul Yang57b65972019-03-19 22:27:13 -070015429static const unsigned char _json_trans_actions[] = {
15430 0, 0, 113, 107, 53, 0, 0, 0,
15431 125, 59, 45, 0, 55, 0, 0, 0,
Paul Yang7f42d6d2019-01-22 15:35:12 -080015432 0, 0, 0, 0, 0, 0, 0, 0,
Paul Yang57b65972019-03-19 22:27:13 -070015433 0, 0, 101, 51, 47, 0, 0, 45,
15434 49, 49, 104, 0, 0, 0, 0, 0,
Paul Yang7f42d6d2019-01-22 15:35:12 -080015435 3, 0, 0, 0, 0, 0, 5, 15,
Paul Yang57b65972019-03-19 22:27:13 -070015436 0, 0, 71, 7, 13, 0, 74, 9,
15437 9, 9, 77, 80, 11, 37, 37, 37,
15438 0, 0, 0, 39, 0, 41, 86, 0,
15439 0, 0, 17, 19, 0, 21, 23, 0,
15440 25, 27, 0, 29, 31, 0, 33, 35,
15441 0, 135, 83, 135, 0, 0, 0, 0,
15442 0, 92, 0, 89, 89, 98, 43, 0,
15443 131, 95, 113, 107, 53, 0, 0, 0,
15444 125, 59, 69, 110, 45, 0, 55, 0,
15445 0, 0, 0, 0, 0, 119, 0, 0,
15446 0, 122, 0, 0, 0, 116, 0, 101,
15447 51, 47, 0, 0, 45, 49, 49, 104,
15448 0, 0, 128, 0, 57, 63, 65, 61,
15449 67
Paul Yang7f42d6d2019-01-22 15:35:12 -080015450};
15451
Paul Yang57b65972019-03-19 22:27:13 -070015452static const unsigned char _json_eof_actions[] = {
Bo Yange3ee7162018-08-10 18:09:02 +000015453 0, 0, 0, 0, 0, 0, 0, 0,
15454 0, 0, 0, 0, 0, 0, 0, 0,
15455 0, 0, 0, 0, 0, 0, 0, 0,
Paul Yang8faa7782018-12-26 10:36:09 -080015456 0, 1, 0, 1, 0, 0, 1, 1,
Bo Yange3ee7162018-08-10 18:09:02 +000015457 0, 0, 0, 0, 0, 0, 0, 0,
15458 0, 0, 0, 0, 0, 0, 0, 0,
15459 0, 0, 0, 0, 0, 0, 0, 0,
Paul Yang9bda1f12018-09-22 18:57:43 -070015460 0, 0, 0, 0, 0, 0, 0, 0,
15461 0, 0, 0, 0, 0, 0, 0, 0,
15462 0, 0, 0, 0, 0, 0, 0, 0,
15463 0, 0, 0, 0, 0, 0, 0, 0,
15464 0, 0, 0, 0, 0, 0, 0, 0,
Paul Yang8faa7782018-12-26 10:36:09 -080015465 0, 0, 0, 0, 0, 0, 0, 0,
Paul Yang57b65972019-03-19 22:27:13 -070015466 0, 0, 0, 57, 63, 65, 61, 67,
Paul Yangc4f2a922019-01-17 10:18:43 -080015467 0, 0, 0, 0, 0, 0
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015468};
15469
15470static const int json_start = 1;
15471
Paul Yang8faa7782018-12-26 10:36:09 -080015472static const int json_en_number_machine = 23;
15473static const int json_en_string_machine = 32;
15474static const int json_en_duration_machine = 40;
15475static const int json_en_timestamp_machine = 47;
Paul Yangc4f2a922019-01-17 10:18:43 -080015476static const int json_en_fieldmask_machine = 75;
15477static const int json_en_value_machine = 78;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015478static const int json_en_main = 1;
15479
15480
Paul Yang57b65972019-03-19 22:27:13 -070015481#line 2827 "upb/json/parser.rl"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015482
15483size_t parse(void *closure, const void *hd, const char *buf, size_t size,
15484 const upb_bufhandle *handle) {
15485 upb_json_parser *parser = closure;
15486
15487 /* Variables used by Ragel's generated code. */
15488 int cs = parser->current_state;
15489 int *stack = parser->parser_stack;
15490 int top = parser->parser_top;
15491
15492 const char *p = buf;
15493 const char *pe = buf + size;
Bo Yange3ee7162018-08-10 18:09:02 +000015494 const char *eof = &eof_ch;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015495
15496 parser->handle = handle;
15497
15498 UPB_UNUSED(hd);
15499 UPB_UNUSED(handle);
15500
15501 capture_resume(parser, buf);
15502
15503
Paul Yang57b65972019-03-19 22:27:13 -070015504#line 2905 "upb/json/parser.c"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015505 {
Paul Yang7f42d6d2019-01-22 15:35:12 -080015506 int _klen;
15507 unsigned int _trans;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015508 const char *_acts;
15509 unsigned int _nacts;
Paul Yang7f42d6d2019-01-22 15:35:12 -080015510 const char *_keys;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015511
15512 if ( p == pe )
15513 goto _test_eof;
15514 if ( cs == 0 )
15515 goto _out;
15516_resume:
Paul Yang7f42d6d2019-01-22 15:35:12 -080015517 _keys = _json_trans_keys + _json_key_offsets[cs];
15518 _trans = _json_index_offsets[cs];
15519
15520 _klen = _json_single_lengths[cs];
15521 if ( _klen > 0 ) {
15522 const char *_lower = _keys;
15523 const char *_mid;
15524 const char *_upper = _keys + _klen - 1;
15525 while (1) {
15526 if ( _upper < _lower )
15527 break;
15528
15529 _mid = _lower + ((_upper-_lower) >> 1);
15530 if ( (*p) < *_mid )
15531 _upper = _mid - 1;
15532 else if ( (*p) > *_mid )
15533 _lower = _mid + 1;
15534 else {
15535 _trans += (unsigned int)(_mid - _keys);
15536 goto _match;
15537 }
15538 }
15539 _keys += _klen;
15540 _trans += _klen;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015541 }
15542
Paul Yang7f42d6d2019-01-22 15:35:12 -080015543 _klen = _json_range_lengths[cs];
15544 if ( _klen > 0 ) {
15545 const char *_lower = _keys;
15546 const char *_mid;
15547 const char *_upper = _keys + (_klen<<1) - 2;
15548 while (1) {
15549 if ( _upper < _lower )
15550 break;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015551
Paul Yang7f42d6d2019-01-22 15:35:12 -080015552 _mid = _lower + (((_upper-_lower) >> 1) & ~1);
15553 if ( (*p) < _mid[0] )
15554 _upper = _mid - 2;
15555 else if ( (*p) > _mid[1] )
15556 _lower = _mid + 2;
15557 else {
15558 _trans += (unsigned int)((_mid - _keys)>>1);
15559 goto _match;
15560 }
15561 }
15562 _trans += _klen;
15563 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015564
Paul Yang7f42d6d2019-01-22 15:35:12 -080015565_match:
15566 _trans = _json_indicies[_trans];
15567 cs = _json_trans_targs[_trans];
15568
15569 if ( _json_trans_actions[_trans] == 0 )
15570 goto _again;
15571
15572 _acts = _json_actions + _json_trans_actions[_trans];
15573 _nacts = (unsigned int) *_acts++;
15574 while ( _nacts-- > 0 )
15575 {
15576 switch ( *_acts++ )
15577 {
Paul Yange0e54662016-09-15 11:09:01 -070015578 case 1:
Paul Yang57b65972019-03-19 22:27:13 -070015579#line 2632 "upb/json/parser.rl"
Paul Yang7f42d6d2019-01-22 15:35:12 -080015580 { p--; {cs = stack[--top]; goto _again;} }
Paul Yange0e54662016-09-15 11:09:01 -070015581 break;
15582 case 2:
Paul Yang57b65972019-03-19 22:27:13 -070015583#line 2634 "upb/json/parser.rl"
Paul Yangc4f2a922019-01-17 10:18:43 -080015584 { p--; {stack[top++] = cs; cs = 23;goto _again;} }
Paul Yange0e54662016-09-15 11:09:01 -070015585 break;
15586 case 3:
Paul Yang57b65972019-03-19 22:27:13 -070015587#line 2638 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015588 { start_text(parser, p); }
Paul Yange0e54662016-09-15 11:09:01 -070015589 break;
15590 case 4:
Paul Yang57b65972019-03-19 22:27:13 -070015591#line 2639 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015592 { CHECK_RETURN_TOP(end_text(parser, p)); }
Paul Yange0e54662016-09-15 11:09:01 -070015593 break;
15594 case 5:
Paul Yang57b65972019-03-19 22:27:13 -070015595#line 2645 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015596 { start_hex(parser); }
Paul Yange0e54662016-09-15 11:09:01 -070015597 break;
15598 case 6:
Paul Yang57b65972019-03-19 22:27:13 -070015599#line 2646 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015600 { hexdigit(parser, p); }
Paul Yange0e54662016-09-15 11:09:01 -070015601 break;
15602 case 7:
Paul Yang57b65972019-03-19 22:27:13 -070015603#line 2647 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015604 { CHECK_RETURN_TOP(end_hex(parser)); }
Paul Yange0e54662016-09-15 11:09:01 -070015605 break;
15606 case 8:
Paul Yang57b65972019-03-19 22:27:13 -070015607#line 2653 "upb/json/parser.rl"
Bo Yange3ee7162018-08-10 18:09:02 +000015608 { CHECK_RETURN_TOP(escape(parser, p)); }
Paul Yange0e54662016-09-15 11:09:01 -070015609 break;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015610 case 9:
Paul Yang57b65972019-03-19 22:27:13 -070015611#line 2659 "upb/json/parser.rl"
Paul Yang7f42d6d2019-01-22 15:35:12 -080015612 { p--; {cs = stack[--top]; goto _again;} }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015613 break;
Bo Yange3ee7162018-08-10 18:09:02 +000015614 case 10:
Paul Yang57b65972019-03-19 22:27:13 -070015615#line 2664 "upb/json/parser.rl"
15616 { start_year(parser, p); }
Bo Yange3ee7162018-08-10 18:09:02 +000015617 break;
15618 case 11:
Paul Yang57b65972019-03-19 22:27:13 -070015619#line 2665 "upb/json/parser.rl"
15620 { CHECK_RETURN_TOP(end_year(parser, p)); }
Bo Yange3ee7162018-08-10 18:09:02 +000015621 break;
15622 case 12:
Paul Yang57b65972019-03-19 22:27:13 -070015623#line 2669 "upb/json/parser.rl"
15624 { start_month(parser, p); }
Bo Yange3ee7162018-08-10 18:09:02 +000015625 break;
Paul Yang9bda1f12018-09-22 18:57:43 -070015626 case 13:
Paul Yang57b65972019-03-19 22:27:13 -070015627#line 2670 "upb/json/parser.rl"
15628 { CHECK_RETURN_TOP(end_month(parser, p)); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015629 break;
15630 case 14:
Paul Yang57b65972019-03-19 22:27:13 -070015631#line 2674 "upb/json/parser.rl"
15632 { start_day(parser, p); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015633 break;
15634 case 15:
Paul Yang57b65972019-03-19 22:27:13 -070015635#line 2675 "upb/json/parser.rl"
15636 { CHECK_RETURN_TOP(end_day(parser, p)); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015637 break;
15638 case 16:
Paul Yang57b65972019-03-19 22:27:13 -070015639#line 2679 "upb/json/parser.rl"
15640 { start_hour(parser, p); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015641 break;
15642 case 17:
Paul Yang57b65972019-03-19 22:27:13 -070015643#line 2680 "upb/json/parser.rl"
15644 { CHECK_RETURN_TOP(end_hour(parser, p)); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015645 break;
15646 case 18:
Paul Yang57b65972019-03-19 22:27:13 -070015647#line 2684 "upb/json/parser.rl"
15648 { start_minute(parser, p); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015649 break;
15650 case 19:
Paul Yang57b65972019-03-19 22:27:13 -070015651#line 2685 "upb/json/parser.rl"
15652 { CHECK_RETURN_TOP(end_minute(parser, p)); }
Paul Yang9bda1f12018-09-22 18:57:43 -070015653 break;
15654 case 20:
Paul Yang57b65972019-03-19 22:27:13 -070015655#line 2689 "upb/json/parser.rl"
15656 { start_second(parser, p); }
Paul Yangc4f2a922019-01-17 10:18:43 -080015657 break;
15658 case 21:
Paul Yang57b65972019-03-19 22:27:13 -070015659#line 2690 "upb/json/parser.rl"
15660 { CHECK_RETURN_TOP(end_second(parser, p)); }
Paul Yangc4f2a922019-01-17 10:18:43 -080015661 break;
15662 case 22:
Paul Yang57b65972019-03-19 22:27:13 -070015663#line 2695 "upb/json/parser.rl"
15664 { start_duration_base(parser, p); }
Paul Yangc4f2a922019-01-17 10:18:43 -080015665 break;
15666 case 23:
Paul Yang57b65972019-03-19 22:27:13 -070015667#line 2696 "upb/json/parser.rl"
15668 { CHECK_RETURN_TOP(end_duration_base(parser, p)); }
Paul Yangc4f2a922019-01-17 10:18:43 -080015669 break;
15670 case 24:
Paul Yang57b65972019-03-19 22:27:13 -070015671#line 2698 "upb/json/parser.rl"
Paul Yang7f42d6d2019-01-22 15:35:12 -080015672 { p--; {cs = stack[--top]; goto _again;} }
Paul Yangc4f2a922019-01-17 10:18:43 -080015673 break;
15674 case 25:
Paul Yang57b65972019-03-19 22:27:13 -070015675#line 2703 "upb/json/parser.rl"
15676 { start_timestamp_base(parser); }
15677 break;
15678 case 26:
15679#line 2705 "upb/json/parser.rl"
15680 { start_timestamp_fraction(parser, p); }
15681 break;
15682 case 27:
15683#line 2706 "upb/json/parser.rl"
15684 { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); }
15685 break;
15686 case 28:
15687#line 2708 "upb/json/parser.rl"
15688 { start_timestamp_zone(parser, p); }
15689 break;
15690 case 29:
15691#line 2709 "upb/json/parser.rl"
15692 { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); }
15693 break;
15694 case 30:
15695#line 2711 "upb/json/parser.rl"
15696 { p--; {cs = stack[--top]; goto _again;} }
15697 break;
15698 case 31:
15699#line 2716 "upb/json/parser.rl"
15700 { start_fieldmask_path_text(parser, p); }
15701 break;
15702 case 32:
15703#line 2717 "upb/json/parser.rl"
15704 { end_fieldmask_path_text(parser, p); }
15705 break;
15706 case 33:
15707#line 2722 "upb/json/parser.rl"
15708 { start_fieldmask_path(parser); }
15709 break;
15710 case 34:
15711#line 2723 "upb/json/parser.rl"
15712 { end_fieldmask_path(parser); }
15713 break;
15714 case 35:
15715#line 2729 "upb/json/parser.rl"
15716 { p--; {cs = stack[--top]; goto _again;} }
15717 break;
15718 case 36:
15719#line 2734 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015720 {
15721 if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
Paul Yangc4f2a922019-01-17 10:18:43 -080015722 {stack[top++] = cs; cs = 47;goto _again;}
Paul Yang9bda1f12018-09-22 18:57:43 -070015723 } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) {
Paul Yangc4f2a922019-01-17 10:18:43 -080015724 {stack[top++] = cs; cs = 40;goto _again;}
15725 } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_FIELDMASK)) {
15726 {stack[top++] = cs; cs = 75;goto _again;}
Paul Yang9bda1f12018-09-22 18:57:43 -070015727 } else {
Paul Yangc4f2a922019-01-17 10:18:43 -080015728 {stack[top++] = cs; cs = 32;goto _again;}
Paul Yang9bda1f12018-09-22 18:57:43 -070015729 }
15730 }
15731 break;
Paul Yang57b65972019-03-19 22:27:13 -070015732 case 37:
15733#line 2747 "upb/json/parser.rl"
Paul Yangc4f2a922019-01-17 10:18:43 -080015734 { p--; {stack[top++] = cs; cs = 78;goto _again;} }
Paul Yang9bda1f12018-09-22 18:57:43 -070015735 break;
Paul Yang57b65972019-03-19 22:27:13 -070015736 case 38:
15737#line 2752 "upb/json/parser.rl"
Paul Yang8faa7782018-12-26 10:36:09 -080015738 {
15739 if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
15740 start_any_member(parser, p);
15741 } else {
15742 start_member(parser);
15743 }
15744 }
Paul Yang9bda1f12018-09-22 18:57:43 -070015745 break;
Paul Yang57b65972019-03-19 22:27:13 -070015746 case 39:
15747#line 2759 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015748 { CHECK_RETURN_TOP(end_membername(parser)); }
15749 break;
Paul Yang57b65972019-03-19 22:27:13 -070015750 case 40:
15751#line 2762 "upb/json/parser.rl"
Paul Yang8faa7782018-12-26 10:36:09 -080015752 {
15753 if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
15754 end_any_member(parser, p);
15755 } else {
15756 end_member(parser);
15757 }
15758 }
Paul Yang9bda1f12018-09-22 18:57:43 -070015759 break;
Paul Yang57b65972019-03-19 22:27:13 -070015760 case 41:
15761#line 2773 "upb/json/parser.rl"
Paul Yang8faa7782018-12-26 10:36:09 -080015762 {
15763 if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
15764 start_any_object(parser, p);
15765 } else {
15766 start_object(parser);
15767 }
15768 }
Paul Yang9bda1f12018-09-22 18:57:43 -070015769 break;
Paul Yang57b65972019-03-19 22:27:13 -070015770 case 42:
15771#line 2782 "upb/json/parser.rl"
Paul Yang8faa7782018-12-26 10:36:09 -080015772 {
15773 if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
15774 CHECK_RETURN_TOP(end_any_object(parser, p));
15775 } else {
15776 end_object(parser);
15777 }
15778 }
Paul Yang9bda1f12018-09-22 18:57:43 -070015779 break;
Paul Yang57b65972019-03-19 22:27:13 -070015780 case 43:
15781#line 2794 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015782 { CHECK_RETURN_TOP(start_array(parser)); }
15783 break;
Paul Yang57b65972019-03-19 22:27:13 -070015784 case 44:
15785#line 2798 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015786 { end_array(parser); }
15787 break;
Paul Yang57b65972019-03-19 22:27:13 -070015788 case 45:
15789#line 2803 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015790 { CHECK_RETURN_TOP(start_number(parser, p)); }
15791 break;
Paul Yang57b65972019-03-19 22:27:13 -070015792 case 46:
15793#line 2804 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015794 { CHECK_RETURN_TOP(end_number(parser, p)); }
15795 break;
Paul Yang57b65972019-03-19 22:27:13 -070015796 case 47:
15797#line 2806 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015798 { CHECK_RETURN_TOP(start_stringval(parser)); }
15799 break;
Paul Yang57b65972019-03-19 22:27:13 -070015800 case 48:
15801#line 2807 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015802 { CHECK_RETURN_TOP(end_stringval(parser)); }
15803 break;
Paul Yang57b65972019-03-19 22:27:13 -070015804 case 49:
15805#line 2809 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015806 { CHECK_RETURN_TOP(end_bool(parser, true)); }
15807 break;
Paul Yang57b65972019-03-19 22:27:13 -070015808 case 50:
15809#line 2811 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015810 { CHECK_RETURN_TOP(end_bool(parser, false)); }
15811 break;
Paul Yang57b65972019-03-19 22:27:13 -070015812 case 51:
15813#line 2813 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015814 { CHECK_RETURN_TOP(end_null(parser)); }
15815 break;
Paul Yang57b65972019-03-19 22:27:13 -070015816 case 52:
15817#line 2815 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015818 { CHECK_RETURN_TOP(start_subobject_full(parser)); }
15819 break;
Paul Yang57b65972019-03-19 22:27:13 -070015820 case 53:
15821#line 2816 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015822 { end_subobject_full(parser); }
15823 break;
Paul Yang57b65972019-03-19 22:27:13 -070015824 case 54:
15825#line 2821 "upb/json/parser.rl"
Paul Yang7f42d6d2019-01-22 15:35:12 -080015826 { p--; {cs = stack[--top]; goto _again;} }
Paul Yang9bda1f12018-09-22 18:57:43 -070015827 break;
Paul Yang57b65972019-03-19 22:27:13 -070015828#line 3229 "upb/json/parser.c"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015829 }
15830 }
15831
15832_again:
15833 if ( cs == 0 )
15834 goto _out;
15835 if ( ++p != pe )
15836 goto _resume;
15837 _test_eof: {}
Bo Yange3ee7162018-08-10 18:09:02 +000015838 if ( p == eof )
15839 {
15840 const char *__acts = _json_actions + _json_eof_actions[cs];
15841 unsigned int __nacts = (unsigned int) *__acts++;
15842 while ( __nacts-- > 0 ) {
15843 switch ( *__acts++ ) {
15844 case 0:
Paul Yang57b65972019-03-19 22:27:13 -070015845#line 2630 "upb/json/parser.rl"
Paul Yang7f42d6d2019-01-22 15:35:12 -080015846 { p--; {cs = stack[--top]; if ( p == pe )
Paul Yangc4f2a922019-01-17 10:18:43 -080015847 goto _test_eof;
15848goto _again;} }
Bo Yange3ee7162018-08-10 18:09:02 +000015849 break;
Paul Yang57b65972019-03-19 22:27:13 -070015850 case 46:
15851#line 2804 "upb/json/parser.rl"
Paul Yangc4f2a922019-01-17 10:18:43 -080015852 { CHECK_RETURN_TOP(end_number(parser, p)); }
15853 break;
Paul Yang57b65972019-03-19 22:27:13 -070015854 case 49:
15855#line 2809 "upb/json/parser.rl"
Paul Yangc4f2a922019-01-17 10:18:43 -080015856 { CHECK_RETURN_TOP(end_bool(parser, true)); }
15857 break;
Paul Yang57b65972019-03-19 22:27:13 -070015858 case 50:
15859#line 2811 "upb/json/parser.rl"
Paul Yangc4f2a922019-01-17 10:18:43 -080015860 { CHECK_RETURN_TOP(end_bool(parser, false)); }
15861 break;
Paul Yang57b65972019-03-19 22:27:13 -070015862 case 51:
15863#line 2813 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015864 { CHECK_RETURN_TOP(end_null(parser)); }
Bo Yange3ee7162018-08-10 18:09:02 +000015865 break;
Paul Yang57b65972019-03-19 22:27:13 -070015866 case 53:
15867#line 2816 "upb/json/parser.rl"
Paul Yang9bda1f12018-09-22 18:57:43 -070015868 { end_subobject_full(parser); }
Bo Yange3ee7162018-08-10 18:09:02 +000015869 break;
Paul Yang57b65972019-03-19 22:27:13 -070015870#line 3271 "upb/json/parser.c"
Bo Yange3ee7162018-08-10 18:09:02 +000015871 }
15872 }
15873 }
15874
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015875 _out: {}
15876 }
15877
Paul Yang57b65972019-03-19 22:27:13 -070015878#line 2849 "upb/json/parser.rl"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015879
15880 if (p != pe) {
Paul Yange0e54662016-09-15 11:09:01 -070015881 upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015882 upb_env_reporterror(parser->env, &parser->status);
15883 } else {
15884 capture_suspend(parser, &p);
15885 }
15886
15887error:
15888 /* Save parsing state back to parser. */
15889 parser->current_state = cs;
15890 parser->parser_top = top;
15891
15892 return p - buf;
15893}
15894
Paul Yang8faa7782018-12-26 10:36:09 -080015895static bool end(void *closure, const void *hd) {
Bo Yange3ee7162018-08-10 18:09:02 +000015896 upb_json_parser *parser = closure;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015897
15898 /* Prevent compile warning on unused static constants. */
15899 UPB_UNUSED(json_start);
Paul Yang9bda1f12018-09-22 18:57:43 -070015900 UPB_UNUSED(json_en_duration_machine);
Paul Yangc4f2a922019-01-17 10:18:43 -080015901 UPB_UNUSED(json_en_fieldmask_machine);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015902 UPB_UNUSED(json_en_number_machine);
15903 UPB_UNUSED(json_en_string_machine);
Paul Yang9bda1f12018-09-22 18:57:43 -070015904 UPB_UNUSED(json_en_timestamp_machine);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015905 UPB_UNUSED(json_en_value_machine);
15906 UPB_UNUSED(json_en_main);
Bo Yange3ee7162018-08-10 18:09:02 +000015907
15908 parse(parser, hd, &eof_ch, 0, NULL);
15909
Paul Yangc4f2a922019-01-17 10:18:43 -080015910 return parser->current_state >= 106;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015911}
15912
15913static void json_parser_reset(upb_json_parser *p) {
15914 int cs;
15915 int top;
15916
15917 p->top = p->stack;
15918 p->top->f = NULL;
Paul Yang4b145b12019-03-12 10:56:58 -070015919 p->top->is_repeated = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015920 p->top->is_map = false;
15921 p->top->is_mapentry = false;
Paul Yang8faa7782018-12-26 10:36:09 -080015922 p->top->is_any = false;
15923 p->top->any_frame = NULL;
Paul Yangd2d4b402018-10-12 13:46:26 -070015924 p->top->is_unknown_field = false;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015925
15926 /* Emit Ragel initialization of the parser. */
15927
Paul Yang57b65972019-03-19 22:27:13 -070015928#line 3329 "upb/json/parser.c"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015929 {
15930 cs = json_start;
15931 top = 0;
15932 }
15933
Paul Yang57b65972019-03-19 22:27:13 -070015934#line 2898 "upb/json/parser.rl"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070015935 p->current_state = cs;
15936 p->parser_top = top;
15937 accumulate_clear(p);
15938 p->multipart_state = MULTIPART_INACTIVE;
15939 p->capture = NULL;
15940 p->accumulated = NULL;
15941 upb_status_clear(&p->status);
15942}
15943
Paul Yange0e54662016-09-15 11:09:01 -070015944static void visit_json_parsermethod(const upb_refcounted *r,
15945 upb_refcounted_visit *visit,
15946 void *closure) {
15947 const upb_json_parsermethod *method = (upb_json_parsermethod*)r;
15948 visit(r, upb_msgdef_upcast2(method->msg), closure);
15949}
15950
15951static void free_json_parsermethod(upb_refcounted *r) {
15952 upb_json_parsermethod *method = (upb_json_parsermethod*)r;
15953
15954 upb_inttable_iter i;
15955 upb_inttable_begin(&i, &method->name_tables);
15956 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
15957 upb_value val = upb_inttable_iter_value(&i);
15958 upb_strtable *t = upb_value_getptr(val);
15959 upb_strtable_uninit(t);
15960 upb_gfree(t);
15961 }
15962
15963 upb_inttable_uninit(&method->name_tables);
15964
15965 upb_gfree(r);
15966}
15967
15968static void add_jsonname_table(upb_json_parsermethod *m, const upb_msgdef* md) {
15969 upb_msg_field_iter i;
15970 upb_strtable *t;
15971
15972 /* It would be nice to stack-allocate this, but protobufs do not limit the
15973 * length of fields to any reasonable limit. */
15974 char *buf = NULL;
15975 size_t len = 0;
15976
15977 if (upb_inttable_lookupptr(&m->name_tables, md, NULL)) {
15978 return;
15979 }
15980
15981 /* TODO(haberman): handle malloc failure. */
15982 t = upb_gmalloc(sizeof(*t));
15983 upb_strtable_init(t, UPB_CTYPE_CONSTPTR);
15984 upb_inttable_insertptr(&m->name_tables, md, upb_value_ptr(t));
15985
15986 for(upb_msg_field_begin(&i, md);
15987 !upb_msg_field_done(&i);
15988 upb_msg_field_next(&i)) {
15989 const upb_fielddef *f = upb_msg_iter_field(&i);
15990
15991 /* Add an entry for the JSON name. */
15992 size_t field_len = upb_fielddef_getjsonname(f, buf, len);
15993 if (field_len > len) {
15994 size_t len2;
15995 buf = upb_grealloc(buf, 0, field_len);
15996 len = field_len;
15997 len2 = upb_fielddef_getjsonname(f, buf, len);
15998 UPB_ASSERT(len == len2);
15999 }
16000 upb_strtable_insert(t, buf, upb_value_constptr(f));
16001
16002 if (strcmp(buf, upb_fielddef_name(f)) != 0) {
16003 /* Since the JSON name is different from the regular field name, add an
16004 * entry for the raw name (compliant proto3 JSON parsers must accept
16005 * both). */
16006 upb_strtable_insert(t, upb_fielddef_name(f), upb_value_constptr(f));
16007 }
16008
16009 if (upb_fielddef_issubmsg(f)) {
16010 add_jsonname_table(m, upb_fielddef_msgsubdef(f));
16011 }
16012 }
16013
16014 upb_gfree(buf);
16015}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016016
16017/* Public API *****************************************************************/
16018
Paul Yange0e54662016-09-15 11:09:01 -070016019upb_json_parser *upb_json_parser_create(upb_env *env,
16020 const upb_json_parsermethod *method,
Paul Yang8faa7782018-12-26 10:36:09 -080016021 const upb_symtab* symtab,
Paul Yang26eeec92018-07-09 14:29:23 -070016022 upb_sink *output,
16023 bool ignore_json_unknown) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016024#ifndef NDEBUG
16025 const size_t size_before = upb_env_bytesallocated(env);
16026#endif
16027 upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser));
16028 if (!p) return false;
16029
16030 p->env = env;
Paul Yange0e54662016-09-15 11:09:01 -070016031 p->method = method;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016032 p->limit = p->stack + UPB_JSON_MAX_DEPTH;
16033 p->accumulate_buf = NULL;
16034 p->accumulate_buf_size = 0;
Paul Yange0e54662016-09-15 11:09:01 -070016035 upb_bytessink_reset(&p->input_, &method->input_handler_, p);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016036
16037 json_parser_reset(p);
16038 upb_sink_reset(&p->top->sink, output->handlers, output->closure);
16039 p->top->m = upb_handlers_msgdef(output->handlers);
Paul Yang8faa7782018-12-26 10:36:09 -080016040 if (is_wellknown_msg(p, UPB_WELLKNOWN_ANY)) {
16041 p->top->is_any = true;
16042 p->top->any_frame =
16043 upb_env_malloc(p->env, sizeof(upb_jsonparser_any_frame));
16044 json_parser_any_frame_reset(p->top->any_frame);
16045 } else {
16046 p->top->is_any = false;
16047 p->top->any_frame = NULL;
16048 }
Paul Yange0e54662016-09-15 11:09:01 -070016049 set_name_table(p, p->top);
Paul Yang8faa7782018-12-26 10:36:09 -080016050 p->symtab = symtab;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016051
Paul Yang26eeec92018-07-09 14:29:23 -070016052 p->ignore_json_unknown = ignore_json_unknown;
16053
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016054 /* If this fails, uncomment and increase the value in parser.h. */
16055 /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
Paul Yange0e54662016-09-15 11:09:01 -070016056 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
16057 UPB_JSON_PARSER_SIZE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016058 return p;
16059}
16060
16061upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
16062 return &p->input_;
16063}
Paul Yange0e54662016-09-15 11:09:01 -070016064
16065upb_json_parsermethod *upb_json_parsermethod_new(const upb_msgdef* md,
16066 const void* owner) {
16067 static const struct upb_refcounted_vtbl vtbl = {visit_json_parsermethod,
16068 free_json_parsermethod};
16069 upb_json_parsermethod *ret = upb_gmalloc(sizeof(*ret));
16070 upb_refcounted_init(upb_json_parsermethod_upcast_mutable(ret), &vtbl, owner);
16071
16072 ret->msg = md;
16073 upb_ref2(md, ret);
16074
16075 upb_byteshandler_init(&ret->input_handler_);
16076 upb_byteshandler_setstring(&ret->input_handler_, parse, ret);
16077 upb_byteshandler_setendstr(&ret->input_handler_, end, ret);
16078
16079 upb_inttable_init(&ret->name_tables, UPB_CTYPE_PTR);
16080
16081 add_jsonname_table(ret, md);
16082
16083 return ret;
16084}
16085
16086const upb_byteshandler *upb_json_parsermethod_inputhandler(
16087 const upb_json_parsermethod *m) {
16088 return &m->input_handler_;
16089}
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016090/*
16091** This currently uses snprintf() to format primitives, and could be optimized
16092** further.
16093*/
16094
16095
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016096#include <string.h>
16097#include <stdint.h>
Paul Yang9bda1f12018-09-22 18:57:43 -070016098#include <time.h>
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016099
16100struct upb_json_printer {
16101 upb_sink input_;
16102 /* BytesSink closure. */
16103 void *subc_;
16104 upb_bytessink *output_;
16105
16106 /* We track the depth so that we know when to emit startstr/endstr on the
16107 * output. */
16108 int depth_;
16109
16110 /* Have we emitted the first element? This state is necessary to emit commas
16111 * without leaving a trailing comma in arrays/maps. We keep this state per
16112 * frame depth.
16113 *
16114 * Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages.
16115 * We count frames (contexts in which we separate elements by commas) as both
16116 * repeated fields and messages (maps), and the worst case is a
16117 * message->repeated field->submessage->repeated field->... nesting. */
16118 bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2];
Paul Yang9bda1f12018-09-22 18:57:43 -070016119
16120 /* To print timestamp, printer needs to cache its seconds and nanos values
16121 * and convert them when ending timestamp message. See comments of
16122 * printer_sethandlers_timestamp for more detail. */
16123 int64_t seconds;
16124 int32_t nanos;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016125};
16126
16127/* StringPiece; a pointer plus a length. */
16128typedef struct {
Paul Yange0e54662016-09-15 11:09:01 -070016129 char *ptr;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016130 size_t len;
16131} strpc;
16132
Paul Yange0e54662016-09-15 11:09:01 -070016133void freestrpc(void *ptr) {
16134 strpc *pc = ptr;
16135 upb_gfree(pc->ptr);
16136 upb_gfree(pc);
16137}
16138
16139/* Convert fielddef name to JSON name and return as a string piece. */
16140strpc *newstrpc(upb_handlers *h, const upb_fielddef *f,
16141 bool preserve_fieldnames) {
16142 /* TODO(haberman): handle malloc failure. */
16143 strpc *ret = upb_gmalloc(sizeof(*ret));
16144 if (preserve_fieldnames) {
16145 ret->ptr = upb_gstrdup(upb_fielddef_name(f));
16146 ret->len = strlen(ret->ptr);
16147 } else {
16148 size_t len;
16149 ret->len = upb_fielddef_getjsonname(f, NULL, 0);
16150 ret->ptr = upb_gmalloc(ret->len);
16151 len = upb_fielddef_getjsonname(f, ret->ptr, ret->len);
16152 UPB_ASSERT(len == ret->len);
16153 ret->len--; /* NULL */
16154 }
16155
16156 upb_handlers_addcleanup(h, ret, freestrpc);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016157 return ret;
16158}
16159
Paul Yang8faa7782018-12-26 10:36:09 -080016160/* Convert a null-terminated const char* to a string piece. */
16161strpc *newstrpc_str(upb_handlers *h, const char * str) {
16162 strpc * ret = upb_gmalloc(sizeof(*ret));
16163 ret->ptr = upb_gstrdup(str);
16164 ret->len = strlen(str);
16165 upb_handlers_addcleanup(h, ret, freestrpc);
16166 return ret;
16167}
16168
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016169/* ------------ JSON string printing: values, maps, arrays ------------------ */
16170
16171static void print_data(
16172 upb_json_printer *p, const char *buf, unsigned int len) {
16173 /* TODO: Will need to change if we support pushback from the sink. */
16174 size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
Paul Yange0e54662016-09-15 11:09:01 -070016175 UPB_ASSERT(n == len);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016176}
16177
16178static void print_comma(upb_json_printer *p) {
16179 if (!p->first_elem_[p->depth_]) {
16180 print_data(p, ",", 1);
16181 }
16182 p->first_elem_[p->depth_] = false;
16183}
16184
16185/* Helpers that print properly formatted elements to the JSON output stream. */
16186
16187/* Used for escaping control chars in strings. */
16188static const char kControlCharLimit = 0x20;
16189
16190UPB_INLINE bool is_json_escaped(char c) {
16191 /* See RFC 4627. */
16192 unsigned char uc = (unsigned char)c;
16193 return uc < kControlCharLimit || uc == '"' || uc == '\\';
16194}
16195
Paul Yange0e54662016-09-15 11:09:01 -070016196UPB_INLINE const char* json_nice_escape(char c) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016197 switch (c) {
16198 case '"': return "\\\"";
16199 case '\\': return "\\\\";
16200 case '\b': return "\\b";
16201 case '\f': return "\\f";
16202 case '\n': return "\\n";
16203 case '\r': return "\\r";
16204 case '\t': return "\\t";
16205 default: return NULL;
16206 }
16207}
16208
16209/* Write a properly escaped string chunk. The surrounding quotes are *not*
16210 * printed; this is so that the caller has the option of emitting the string
16211 * content in chunks. */
16212static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
16213 const char* unescaped_run = NULL;
16214 unsigned int i;
16215 for (i = 0; i < len; i++) {
16216 char c = buf[i];
16217 /* Handle escaping. */
16218 if (is_json_escaped(c)) {
16219 /* Use a "nice" escape, like \n, if one exists for this character. */
16220 const char* escape = json_nice_escape(c);
16221 /* If we don't have a specific 'nice' escape code, use a \uXXXX-style
16222 * escape. */
16223 char escape_buf[8];
16224 if (!escape) {
16225 unsigned char byte = (unsigned char)c;
16226 _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
16227 escape = escape_buf;
16228 }
16229
16230 /* N.B. that we assume that the input encoding is equal to the output
16231 * encoding (both UTF-8 for now), so for chars >= 0x20 and != \, ", we
16232 * can simply pass the bytes through. */
16233
16234 /* If there's a current run of unescaped chars, print that run first. */
16235 if (unescaped_run) {
16236 print_data(p, unescaped_run, &buf[i] - unescaped_run);
16237 unescaped_run = NULL;
16238 }
16239 /* Then print the escape code. */
16240 print_data(p, escape, strlen(escape));
16241 } else {
16242 /* Add to the current unescaped run of characters. */
16243 if (unescaped_run == NULL) {
16244 unescaped_run = &buf[i];
16245 }
16246 }
16247 }
16248
16249 /* If the string ended in a run of unescaped characters, print that last run. */
16250 if (unescaped_run) {
16251 print_data(p, unescaped_run, &buf[len] - unescaped_run);
16252 }
16253}
16254
16255#define CHKLENGTH(x) if (!(x)) return -1;
16256
16257/* Helpers that format floating point values according to our custom formats.
16258 * Right now we use %.8g and %.17g for float/double, respectively, to match
16259 * proto2::util::JsonFormat's defaults. May want to change this later. */
16260
Paul Yang60327462017-10-09 12:39:13 -070016261const char neginf[] = "\"-Infinity\"";
16262const char inf[] = "\"Infinity\"";
16263
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016264static size_t fmt_double(double val, char* buf, size_t length) {
Paul Yang60327462017-10-09 12:39:13 -070016265 if (val == (1.0 / 0.0)) {
16266 CHKLENGTH(length >= strlen(inf));
16267 strcpy(buf, inf);
16268 return strlen(inf);
16269 } else if (val == (-1.0 / 0.0)) {
16270 CHKLENGTH(length >= strlen(neginf));
16271 strcpy(buf, neginf);
16272 return strlen(neginf);
16273 } else {
16274 size_t n = _upb_snprintf(buf, length, "%.17g", val);
16275 CHKLENGTH(n > 0 && n < length);
16276 return n;
16277 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016278}
16279
16280static size_t fmt_float(float val, char* buf, size_t length) {
16281 size_t n = _upb_snprintf(buf, length, "%.8g", val);
16282 CHKLENGTH(n > 0 && n < length);
16283 return n;
16284}
16285
16286static size_t fmt_bool(bool val, char* buf, size_t length) {
16287 size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false"));
16288 CHKLENGTH(n > 0 && n < length);
16289 return n;
16290}
16291
16292static size_t fmt_int64(long val, char* buf, size_t length) {
16293 size_t n = _upb_snprintf(buf, length, "%ld", val);
16294 CHKLENGTH(n > 0 && n < length);
16295 return n;
16296}
16297
16298static size_t fmt_uint64(unsigned long long val, char* buf, size_t length) {
16299 size_t n = _upb_snprintf(buf, length, "%llu", val);
16300 CHKLENGTH(n > 0 && n < length);
16301 return n;
16302}
16303
16304/* Print a map key given a field name. Called by scalar field handlers and by
16305 * startseq for repeated fields. */
16306static bool putkey(void *closure, const void *handler_data) {
16307 upb_json_printer *p = closure;
16308 const strpc *key = handler_data;
16309 print_comma(p);
16310 print_data(p, "\"", 1);
16311 putstring(p, key->ptr, key->len);
16312 print_data(p, "\":", 2);
16313 return true;
16314}
16315
16316#define CHKFMT(val) if ((val) == (size_t)-1) return false;
16317#define CHK(val) if (!(val)) return false;
16318
16319#define TYPE_HANDLERS(type, fmt_func) \
16320 static bool put##type(void *closure, const void *handler_data, type val) { \
16321 upb_json_printer *p = closure; \
16322 char data[64]; \
16323 size_t length = fmt_func(val, data, sizeof(data)); \
16324 UPB_UNUSED(handler_data); \
16325 CHKFMT(length); \
16326 print_data(p, data, length); \
16327 return true; \
16328 } \
16329 static bool scalar_##type(void *closure, const void *handler_data, \
16330 type val) { \
16331 CHK(putkey(closure, handler_data)); \
16332 CHK(put##type(closure, handler_data, val)); \
16333 return true; \
16334 } \
16335 static bool repeated_##type(void *closure, const void *handler_data, \
16336 type val) { \
16337 upb_json_printer *p = closure; \
16338 print_comma(p); \
16339 CHK(put##type(closure, handler_data, val)); \
16340 return true; \
16341 }
16342
16343#define TYPE_HANDLERS_MAPKEY(type, fmt_func) \
16344 static bool putmapkey_##type(void *closure, const void *handler_data, \
16345 type val) { \
16346 upb_json_printer *p = closure; \
16347 print_data(p, "\"", 1); \
16348 CHK(put##type(closure, handler_data, val)); \
16349 print_data(p, "\":", 2); \
16350 return true; \
16351 }
16352
16353TYPE_HANDLERS(double, fmt_double)
16354TYPE_HANDLERS(float, fmt_float)
16355TYPE_HANDLERS(bool, fmt_bool)
16356TYPE_HANDLERS(int32_t, fmt_int64)
16357TYPE_HANDLERS(uint32_t, fmt_int64)
16358TYPE_HANDLERS(int64_t, fmt_int64)
16359TYPE_HANDLERS(uint64_t, fmt_uint64)
16360
16361/* double and float are not allowed to be map keys. */
16362TYPE_HANDLERS_MAPKEY(bool, fmt_bool)
16363TYPE_HANDLERS_MAPKEY(int32_t, fmt_int64)
16364TYPE_HANDLERS_MAPKEY(uint32_t, fmt_int64)
16365TYPE_HANDLERS_MAPKEY(int64_t, fmt_int64)
16366TYPE_HANDLERS_MAPKEY(uint64_t, fmt_uint64)
16367
16368#undef TYPE_HANDLERS
16369#undef TYPE_HANDLERS_MAPKEY
16370
16371typedef struct {
16372 void *keyname;
16373 const upb_enumdef *enumdef;
16374} EnumHandlerData;
16375
16376static bool scalar_enum(void *closure, const void *handler_data,
16377 int32_t val) {
16378 const EnumHandlerData *hd = handler_data;
16379 upb_json_printer *p = closure;
16380 const char *symbolic_name;
16381
16382 CHK(putkey(closure, hd->keyname));
16383
16384 symbolic_name = upb_enumdef_iton(hd->enumdef, val);
16385 if (symbolic_name) {
16386 print_data(p, "\"", 1);
16387 putstring(p, symbolic_name, strlen(symbolic_name));
16388 print_data(p, "\"", 1);
16389 } else {
16390 putint32_t(closure, NULL, val);
16391 }
16392
16393 return true;
16394}
16395
16396static void print_enum_symbolic_name(upb_json_printer *p,
16397 const upb_enumdef *def,
16398 int32_t val) {
16399 const char *symbolic_name = upb_enumdef_iton(def, val);
16400 if (symbolic_name) {
16401 print_data(p, "\"", 1);
16402 putstring(p, symbolic_name, strlen(symbolic_name));
16403 print_data(p, "\"", 1);
16404 } else {
16405 putint32_t(p, NULL, val);
16406 }
16407}
16408
16409static bool repeated_enum(void *closure, const void *handler_data,
16410 int32_t val) {
16411 const EnumHandlerData *hd = handler_data;
16412 upb_json_printer *p = closure;
16413 print_comma(p);
16414
16415 print_enum_symbolic_name(p, hd->enumdef, val);
16416
16417 return true;
16418}
16419
16420static bool mapvalue_enum(void *closure, const void *handler_data,
16421 int32_t val) {
16422 const EnumHandlerData *hd = handler_data;
16423 upb_json_printer *p = closure;
16424
16425 print_enum_symbolic_name(p, hd->enumdef, val);
16426
16427 return true;
16428}
16429
16430static void *scalar_startsubmsg(void *closure, const void *handler_data) {
16431 return putkey(closure, handler_data) ? closure : UPB_BREAK;
16432}
16433
16434static void *repeated_startsubmsg(void *closure, const void *handler_data) {
16435 upb_json_printer *p = closure;
16436 UPB_UNUSED(handler_data);
16437 print_comma(p);
16438 return closure;
16439}
16440
16441static void start_frame(upb_json_printer *p) {
16442 p->depth_++;
16443 p->first_elem_[p->depth_] = true;
16444 print_data(p, "{", 1);
16445}
16446
16447static void end_frame(upb_json_printer *p) {
16448 print_data(p, "}", 1);
16449 p->depth_--;
16450}
16451
16452static bool printer_startmsg(void *closure, const void *handler_data) {
16453 upb_json_printer *p = closure;
16454 UPB_UNUSED(handler_data);
16455 if (p->depth_ == 0) {
16456 upb_bytessink_start(p->output_, 0, &p->subc_);
16457 }
16458 start_frame(p);
16459 return true;
16460}
16461
16462static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) {
16463 upb_json_printer *p = closure;
16464 UPB_UNUSED(handler_data);
16465 UPB_UNUSED(s);
16466 end_frame(p);
16467 if (p->depth_ == 0) {
16468 upb_bytessink_end(p->output_);
16469 }
16470 return true;
16471}
16472
16473static void *startseq(void *closure, const void *handler_data) {
16474 upb_json_printer *p = closure;
16475 CHK(putkey(closure, handler_data));
16476 p->depth_++;
16477 p->first_elem_[p->depth_] = true;
16478 print_data(p, "[", 1);
16479 return closure;
16480}
16481
16482static bool endseq(void *closure, const void *handler_data) {
16483 upb_json_printer *p = closure;
16484 UPB_UNUSED(handler_data);
16485 print_data(p, "]", 1);
16486 p->depth_--;
16487 return true;
16488}
16489
16490static void *startmap(void *closure, const void *handler_data) {
16491 upb_json_printer *p = closure;
16492 CHK(putkey(closure, handler_data));
16493 p->depth_++;
16494 p->first_elem_[p->depth_] = true;
16495 print_data(p, "{", 1);
16496 return closure;
16497}
16498
16499static bool endmap(void *closure, const void *handler_data) {
16500 upb_json_printer *p = closure;
16501 UPB_UNUSED(handler_data);
16502 print_data(p, "}", 1);
16503 p->depth_--;
16504 return true;
16505}
16506
16507static size_t putstr(void *closure, const void *handler_data, const char *str,
16508 size_t len, const upb_bufhandle *handle) {
16509 upb_json_printer *p = closure;
16510 UPB_UNUSED(handler_data);
16511 UPB_UNUSED(handle);
16512 putstring(p, str, len);
16513 return len;
16514}
16515
16516/* This has to Base64 encode the bytes, because JSON has no "bytes" type. */
16517static size_t putbytes(void *closure, const void *handler_data, const char *str,
16518 size_t len, const upb_bufhandle *handle) {
16519 upb_json_printer *p = closure;
16520
16521 /* This is the regular base64, not the "web-safe" version. */
16522 static const char base64[] =
16523 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16524
16525 /* Base64-encode. */
16526 char data[16000];
16527 const char *limit = data + sizeof(data);
16528 const unsigned char *from = (const unsigned char*)str;
16529 char *to = data;
16530 size_t remaining = len;
16531 size_t bytes;
16532
16533 UPB_UNUSED(handler_data);
16534 UPB_UNUSED(handle);
16535
Paul Yangba42cb52019-03-25 10:51:18 -070016536 print_data(p, "\"", 1);
16537
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016538 while (remaining > 2) {
Paul Yangba42cb52019-03-25 10:51:18 -070016539 if (limit - to < 4) {
16540 bytes = to - data;
16541 putstring(p, data, bytes);
16542 to = data;
16543 }
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016544
16545 to[0] = base64[from[0] >> 2];
16546 to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
16547 to[2] = base64[((from[1] & 0xf) << 2) | (from[2] >> 6)];
16548 to[3] = base64[from[2] & 0x3f];
16549
16550 remaining -= 3;
16551 to += 4;
16552 from += 3;
16553 }
16554
16555 switch (remaining) {
16556 case 2:
16557 to[0] = base64[from[0] >> 2];
16558 to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
16559 to[2] = base64[(from[1] & 0xf) << 2];
16560 to[3] = '=';
16561 to += 4;
16562 from += 2;
16563 break;
16564 case 1:
16565 to[0] = base64[from[0] >> 2];
16566 to[1] = base64[((from[0] & 0x3) << 4)];
16567 to[2] = '=';
16568 to[3] = '=';
16569 to += 4;
16570 from += 1;
16571 break;
16572 }
16573
16574 bytes = to - data;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016575 putstring(p, data, bytes);
16576 print_data(p, "\"", 1);
16577 return len;
16578}
16579
16580static void *scalar_startstr(void *closure, const void *handler_data,
16581 size_t size_hint) {
16582 upb_json_printer *p = closure;
16583 UPB_UNUSED(handler_data);
16584 UPB_UNUSED(size_hint);
16585 CHK(putkey(closure, handler_data));
16586 print_data(p, "\"", 1);
16587 return p;
16588}
16589
16590static size_t scalar_str(void *closure, const void *handler_data,
16591 const char *str, size_t len,
16592 const upb_bufhandle *handle) {
16593 CHK(putstr(closure, handler_data, str, len, handle));
16594 return len;
16595}
16596
16597static bool scalar_endstr(void *closure, const void *handler_data) {
16598 upb_json_printer *p = closure;
16599 UPB_UNUSED(handler_data);
16600 print_data(p, "\"", 1);
16601 return true;
16602}
16603
16604static void *repeated_startstr(void *closure, const void *handler_data,
16605 size_t size_hint) {
16606 upb_json_printer *p = closure;
16607 UPB_UNUSED(handler_data);
16608 UPB_UNUSED(size_hint);
16609 print_comma(p);
16610 print_data(p, "\"", 1);
16611 return p;
16612}
16613
16614static size_t repeated_str(void *closure, const void *handler_data,
16615 const char *str, size_t len,
16616 const upb_bufhandle *handle) {
16617 CHK(putstr(closure, handler_data, str, len, handle));
16618 return len;
16619}
16620
16621static bool repeated_endstr(void *closure, const void *handler_data) {
16622 upb_json_printer *p = closure;
16623 UPB_UNUSED(handler_data);
16624 print_data(p, "\"", 1);
16625 return true;
16626}
16627
16628static void *mapkeyval_startstr(void *closure, const void *handler_data,
16629 size_t size_hint) {
16630 upb_json_printer *p = closure;
16631 UPB_UNUSED(handler_data);
16632 UPB_UNUSED(size_hint);
16633 print_data(p, "\"", 1);
16634 return p;
16635}
16636
16637static size_t mapkey_str(void *closure, const void *handler_data,
16638 const char *str, size_t len,
16639 const upb_bufhandle *handle) {
16640 CHK(putstr(closure, handler_data, str, len, handle));
16641 return len;
16642}
16643
16644static bool mapkey_endstr(void *closure, const void *handler_data) {
16645 upb_json_printer *p = closure;
16646 UPB_UNUSED(handler_data);
16647 print_data(p, "\":", 2);
16648 return true;
16649}
16650
16651static bool mapvalue_endstr(void *closure, const void *handler_data) {
16652 upb_json_printer *p = closure;
16653 UPB_UNUSED(handler_data);
16654 print_data(p, "\"", 1);
16655 return true;
16656}
16657
16658static size_t scalar_bytes(void *closure, const void *handler_data,
16659 const char *str, size_t len,
16660 const upb_bufhandle *handle) {
16661 CHK(putkey(closure, handler_data));
16662 CHK(putbytes(closure, handler_data, str, len, handle));
16663 return len;
16664}
16665
16666static size_t repeated_bytes(void *closure, const void *handler_data,
16667 const char *str, size_t len,
16668 const upb_bufhandle *handle) {
16669 upb_json_printer *p = closure;
16670 print_comma(p);
16671 CHK(putbytes(closure, handler_data, str, len, handle));
16672 return len;
16673}
16674
16675static size_t mapkey_bytes(void *closure, const void *handler_data,
16676 const char *str, size_t len,
16677 const upb_bufhandle *handle) {
16678 upb_json_printer *p = closure;
16679 CHK(putbytes(closure, handler_data, str, len, handle));
16680 print_data(p, ":", 1);
16681 return len;
16682}
16683
16684static void set_enum_hd(upb_handlers *h,
16685 const upb_fielddef *f,
Paul Yange0e54662016-09-15 11:09:01 -070016686 bool preserve_fieldnames,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016687 upb_handlerattr *attr) {
Paul Yange0e54662016-09-15 11:09:01 -070016688 EnumHandlerData *hd = upb_gmalloc(sizeof(EnumHandlerData));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016689 hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
Paul Yange0e54662016-09-15 11:09:01 -070016690 hd->keyname = newstrpc(h, f, preserve_fieldnames);
16691 upb_handlers_addcleanup(h, hd, upb_gfree);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016692 upb_handlerattr_sethandlerdata(attr, hd);
16693}
16694
16695/* Set up handlers for a mapentry submessage (i.e., an individual key/value pair
16696 * in a map).
16697 *
16698 * TODO: Handle missing key, missing value, out-of-order key/value, or repeated
16699 * key or value cases properly. The right way to do this is to allocate a
16700 * temporary structure at the start of a mapentry submessage, store key and
16701 * value data in it as key and value handlers are called, and then print the
16702 * key/value pair once at the end of the submessage. If we don't do this, we
16703 * should at least detect the case and throw an error. However, so far all of
16704 * our sources that emit mapentry messages do so canonically (with one key
16705 * field, and then one value field), so this is not a pressing concern at the
16706 * moment. */
Paul Yange0e54662016-09-15 11:09:01 -070016707void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames,
16708 upb_handlers *h) {
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016709 const upb_msgdef *md = upb_handlers_msgdef(h);
16710
16711 /* A mapentry message is printed simply as '"key": value'. Rather than
16712 * special-case key and value for every type below, we just handle both
16713 * fields explicitly here. */
16714 const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY);
16715 const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE);
16716
16717 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
16718
16719 UPB_UNUSED(closure);
16720
16721 switch (upb_fielddef_type(key_field)) {
16722 case UPB_TYPE_INT32:
16723 upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr);
16724 break;
16725 case UPB_TYPE_INT64:
16726 upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr);
16727 break;
16728 case UPB_TYPE_UINT32:
16729 upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr);
16730 break;
16731 case UPB_TYPE_UINT64:
16732 upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr);
16733 break;
16734 case UPB_TYPE_BOOL:
16735 upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr);
16736 break;
16737 case UPB_TYPE_STRING:
16738 upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr);
16739 upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr);
16740 upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr);
16741 break;
16742 case UPB_TYPE_BYTES:
16743 upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr);
16744 break;
16745 default:
Paul Yange0e54662016-09-15 11:09:01 -070016746 UPB_ASSERT(false);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016747 break;
16748 }
16749
16750 switch (upb_fielddef_type(value_field)) {
16751 case UPB_TYPE_INT32:
16752 upb_handlers_setint32(h, value_field, putint32_t, &empty_attr);
16753 break;
16754 case UPB_TYPE_INT64:
16755 upb_handlers_setint64(h, value_field, putint64_t, &empty_attr);
16756 break;
16757 case UPB_TYPE_UINT32:
16758 upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr);
16759 break;
16760 case UPB_TYPE_UINT64:
16761 upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr);
16762 break;
16763 case UPB_TYPE_BOOL:
16764 upb_handlers_setbool(h, value_field, putbool, &empty_attr);
16765 break;
16766 case UPB_TYPE_FLOAT:
16767 upb_handlers_setfloat(h, value_field, putfloat, &empty_attr);
16768 break;
16769 case UPB_TYPE_DOUBLE:
16770 upb_handlers_setdouble(h, value_field, putdouble, &empty_attr);
16771 break;
16772 case UPB_TYPE_STRING:
16773 upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr);
16774 upb_handlers_setstring(h, value_field, putstr, &empty_attr);
16775 upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr);
16776 break;
16777 case UPB_TYPE_BYTES:
16778 upb_handlers_setstring(h, value_field, putbytes, &empty_attr);
16779 break;
16780 case UPB_TYPE_ENUM: {
16781 upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
Paul Yange0e54662016-09-15 11:09:01 -070016782 set_enum_hd(h, value_field, preserve_fieldnames, &enum_attr);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070016783 upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
16784 upb_handlerattr_uninit(&enum_attr);
16785 break;
16786 }
16787 case UPB_TYPE_MESSAGE:
16788 /* No handler necessary -- the submsg handlers will print the message
16789 * as appropriate. */
16790 break;
16791 }
16792
16793 upb_handlerattr_uninit(&empty_attr);
16794}
16795
Paul Yang9bda1f12018-09-22 18:57:43 -070016796static bool putseconds(void *closure, const void *handler_data,
16797 int64_t seconds) {
16798 upb_json_printer *p = closure;
16799 p->seconds = seconds;
16800 UPB_UNUSED(handler_data);
16801 return true;
16802}
16803
16804static bool putnanos(void *closure, const void *handler_data,
16805 int32_t nanos) {
16806 upb_json_printer *p = closure;
16807 p->nanos = nanos;
16808 UPB_UNUSED(handler_data);
16809 return true;
16810}
16811
16812static void *scalar_startstr_nokey(void *closure, const void *handler_data,
16813 size_t size_hint) {
16814 upb_json_printer *p = closure;
16815 UPB_UNUSED(handler_data);
16816 UPB_UNUSED(size_hint);
16817 print_data(p, "\"", 1);
16818 return p;
16819}
16820
16821static size_t putstr_nokey(void *closure, const void *handler_data,
16822 const char *str, size_t len,
16823 const upb_bufhandle *handle) {
16824 upb_json_printer *p = closure;
16825 UPB_UNUSED(handler_data);
16826 UPB_UNUSED(handle);
16827 print_data(p, "\"", 1);
16828 putstring(p, str, len);
16829 print_data(p, "\"", 1);
16830 return len + 2;
16831}
16832
16833static void *startseq_nokey(void *closure, const void *handler_data) {
16834 upb_json_printer *p = closure;
16835 UPB_UNUSED(handler_data);
16836 p->depth_++;
16837 p->first_elem_[p->depth_] = true;
16838 print_data(p, "[", 1);
16839 return closure;
16840}
16841
Paul Yangc4f2a922019-01-17 10:18:43 -080016842static void *startseq_fieldmask(void *closure, const void *handler_data) {
16843 upb_json_printer *p = closure;
16844 UPB_UNUSED(handler_data);
16845 p->depth_++;
16846 p->first_elem_[p->depth_] = true;
Paul Yangc4f2a922019-01-17 10:18:43 -080016847 return closure;
16848}
16849
16850static bool endseq_fieldmask(void *closure, const void *handler_data) {
16851 upb_json_printer *p = closure;
16852 UPB_UNUSED(handler_data);
16853 p->depth_--;
Paul Yangc4f2a922019-01-17 10:18:43 -080016854 return true;
16855}
16856
16857static void *repeated_startstr_fieldmask(
16858 void *closure, const void *handler_data,
16859 size_t size_hint) {
16860 upb_json_printer *p = closure;
16861 UPB_UNUSED(handler_data);
16862 UPB_UNUSED(size_hint);
16863 print_comma(p);
16864 return p;
16865}
16866
16867static size_t repeated_str_fieldmask(
16868 void *closure, const void *handler_data,
16869 const char *str, size_t len,
16870 const upb_bufhandle *handle) {
16871 const char* limit = str + len;
16872 bool upper = false;
16873 size_t result_len = 0;
16874 for (; str < limit; str++) {
16875 if (*str == '_') {
16876 upper = true;
16877 continue;
16878 }
16879 if (upper && *str >= 'a' && *str <= 'z') {
16880 char upper_char = toupper(*str);
16881 CHK(putstr(closure, handler_data, &upper_char, 1, handle));
16882 } else {
16883 CHK(putstr(closure, handler_data, str, 1, handle));
16884 }
16885 upper = false;
16886 result_len++;
16887 }
16888 return result_len;
16889}
16890
Paul Yang9bda1f12018-09-22 18:57:43 -070016891static void *startmap_nokey(void *closure, const void *handler_data) {
16892 upb_json_printer *p = closure;
16893 UPB_UNUSED(handler_data);
16894 p->depth_++;
16895 p->first_elem_[p->depth_] = true;
16896 print_data(p, "{", 1);
16897 return closure;
16898}
16899
16900static bool putnull(void *closure, const void *handler_data,
16901 int32_t null) {
16902 upb_json_printer *p = closure;
16903 print_data(p, "null", 4);
16904 UPB_UNUSED(handler_data);
16905 UPB_UNUSED(null);
16906 return true;
16907}
16908
16909static bool printer_startdurationmsg(void *closure, const void *handler_data) {
16910 upb_json_printer *p = closure;
16911 UPB_UNUSED(handler_data);
16912 if (p->depth_ == 0) {
16913 upb_bytessink_start(p->output_, 0, &p->subc_);
16914 }
16915 return true;
16916}
16917
16918#define UPB_DURATION_MAX_JSON_LEN 23
16919#define UPB_DURATION_MAX_NANO_LEN 9
16920
16921static bool printer_enddurationmsg(void *closure, const void *handler_data,
16922 upb_status *s) {
16923 upb_json_printer *p = closure;
16924 char buffer[UPB_DURATION_MAX_JSON_LEN];
16925 size_t base_len;
16926 size_t curr;
16927 size_t i;
16928
16929 memset(buffer, 0, UPB_DURATION_MAX_JSON_LEN);
16930
16931 if (p->seconds < -315576000000) {
16932 upb_status_seterrf(s, "error parsing duration: "
16933 "minimum acceptable value is "
16934 "-315576000000");
16935 return false;
16936 }
16937
16938 if (p->seconds > 315576000000) {
16939 upb_status_seterrf(s, "error serializing duration: "
16940 "maximum acceptable value is "
16941 "315576000000");
16942 return false;
16943 }
16944
16945 _upb_snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds);
16946 base_len = strlen(buffer);
16947
16948 if (p->nanos != 0) {
16949 char nanos_buffer[UPB_DURATION_MAX_NANO_LEN + 3];
16950 _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
16951 p->nanos / 1000000000.0);
16952 /* Remove trailing 0. */
16953 for (i = UPB_DURATION_MAX_NANO_LEN + 2;
16954 nanos_buffer[i] == '0'; i--) {
16955 nanos_buffer[i] = 0;
16956 }
16957 strcpy(buffer + base_len, nanos_buffer + 1);
16958 }
16959
16960 curr = strlen(buffer);
16961 strcpy(buffer + curr, "s");
16962
16963 p->seconds = 0;
16964 p->nanos = 0;
16965
16966 print_data(p, "\"", 1);
16967 print_data(p, buffer, strlen(buffer));
16968 print_data(p, "\"", 1);
16969
16970 if (p->depth_ == 0) {
16971 upb_bytessink_end(p->output_);
16972 }
16973
16974 UPB_UNUSED(handler_data);
16975 return true;
16976}
16977
16978static bool printer_starttimestampmsg(void *closure, const void *handler_data) {
16979 upb_json_printer *p = closure;
16980 UPB_UNUSED(handler_data);
16981 if (p->depth_ == 0) {
16982 upb_bytessink_start(p->output_, 0, &p->subc_);
16983 }
16984 return true;
16985}
16986
16987#define UPB_TIMESTAMP_MAX_JSON_LEN 31
16988#define UPB_TIMESTAMP_BEFORE_NANO_LEN 19
16989#define UPB_TIMESTAMP_MAX_NANO_LEN 9
16990
16991static bool printer_endtimestampmsg(void *closure, const void *handler_data,
16992 upb_status *s) {
16993 upb_json_printer *p = closure;
16994 char buffer[UPB_TIMESTAMP_MAX_JSON_LEN];
16995 time_t time = p->seconds;
16996 size_t curr;
16997 size_t i;
16998 size_t year_length =
16999 strftime(buffer, UPB_TIMESTAMP_MAX_JSON_LEN, "%Y", gmtime(&time));
17000
17001 if (p->seconds < -62135596800) {
17002 upb_status_seterrf(s, "error parsing timestamp: "
17003 "minimum acceptable value is "
17004 "0001-01-01T00:00:00Z");
17005 return false;
17006 }
17007
17008 if (p->seconds > 253402300799) {
17009 upb_status_seterrf(s, "error parsing timestamp: "
17010 "maximum acceptable value is "
17011 "9999-12-31T23:59:59Z");
17012 return false;
17013 }
17014
17015 /* strftime doesn't guarantee 4 digits for year. Prepend 0 by ourselves. */
17016 for (i = 0; i < 4 - year_length; i++) {
17017 buffer[i] = '0';
17018 }
17019
17020 strftime(buffer + (4 - year_length), UPB_TIMESTAMP_MAX_JSON_LEN,
17021 "%Y-%m-%dT%H:%M:%S", gmtime(&time));
17022 if (p->nanos != 0) {
17023 char nanos_buffer[UPB_TIMESTAMP_MAX_NANO_LEN + 3];
17024 _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
17025 p->nanos / 1000000000.0);
17026 /* Remove trailing 0. */
17027 for (i = UPB_TIMESTAMP_MAX_NANO_LEN + 2;
17028 nanos_buffer[i] == '0'; i--) {
17029 nanos_buffer[i] = 0;
17030 }
17031 strcpy(buffer + UPB_TIMESTAMP_BEFORE_NANO_LEN, nanos_buffer + 1);
17032 }
17033
17034 curr = strlen(buffer);
17035 strcpy(buffer + curr, "Z");
17036
17037 p->seconds = 0;
17038 p->nanos = 0;
17039
17040 print_data(p, "\"", 1);
17041 print_data(p, buffer, strlen(buffer));
17042 print_data(p, "\"", 1);
17043
17044 if (p->depth_ == 0) {
17045 upb_bytessink_end(p->output_);
17046 }
17047
17048 UPB_UNUSED(handler_data);
17049 UPB_UNUSED(s);
17050 return true;
17051}
17052
17053static bool printer_startmsg_noframe(void *closure, const void *handler_data) {
17054 upb_json_printer *p = closure;
17055 UPB_UNUSED(handler_data);
17056 if (p->depth_ == 0) {
17057 upb_bytessink_start(p->output_, 0, &p->subc_);
17058 }
17059 return true;
17060}
17061
17062static bool printer_endmsg_noframe(
17063 void *closure, const void *handler_data, upb_status *s) {
17064 upb_json_printer *p = closure;
17065 UPB_UNUSED(handler_data);
17066 UPB_UNUSED(s);
17067 if (p->depth_ == 0) {
17068 upb_bytessink_end(p->output_);
17069 }
17070 return true;
17071}
17072
Paul Yang7f42d6d2019-01-22 15:35:12 -080017073static bool printer_startmsg_fieldmask(
17074 void *closure, const void *handler_data) {
17075 upb_json_printer *p = closure;
17076 UPB_UNUSED(handler_data);
17077 if (p->depth_ == 0) {
17078 upb_bytessink_start(p->output_, 0, &p->subc_);
17079 }
17080 print_data(p, "\"", 1);
17081 return true;
17082}
17083
17084static bool printer_endmsg_fieldmask(
17085 void *closure, const void *handler_data, upb_status *s) {
17086 upb_json_printer *p = closure;
17087 UPB_UNUSED(handler_data);
17088 UPB_UNUSED(s);
17089 print_data(p, "\"", 1);
17090 if (p->depth_ == 0) {
17091 upb_bytessink_end(p->output_);
17092 }
17093 return true;
17094}
17095
Paul Yang8faa7782018-12-26 10:36:09 -080017096static void *scalar_startstr_onlykey(
17097 void *closure, const void *handler_data, size_t size_hint) {
17098 upb_json_printer *p = closure;
17099 UPB_UNUSED(size_hint);
17100 CHK(putkey(closure, handler_data));
17101 return p;
17102}
17103
17104/* Set up handlers for an Any submessage. */
17105void printer_sethandlers_any(const void *closure, upb_handlers *h) {
17106 const upb_msgdef *md = upb_handlers_msgdef(h);
17107
17108 const upb_fielddef* type_field = upb_msgdef_itof(md, UPB_ANY_TYPE);
17109 const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_ANY_VALUE);
17110
17111 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17112
17113 /* type_url's json name is "@type" */
17114 upb_handlerattr type_name_attr = UPB_HANDLERATTR_INITIALIZER;
17115 upb_handlerattr value_name_attr = UPB_HANDLERATTR_INITIALIZER;
17116 strpc *type_url_json_name = newstrpc_str(h, "@type");
17117 strpc *value_json_name = newstrpc_str(h, "value");
17118
17119 upb_handlerattr_sethandlerdata(&type_name_attr, type_url_json_name);
17120 upb_handlerattr_sethandlerdata(&value_name_attr, value_json_name);
17121
17122 /* Set up handlers. */
17123 upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
17124 upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
17125
17126 upb_handlers_setstartstr(h, type_field, scalar_startstr, &type_name_attr);
17127 upb_handlers_setstring(h, type_field, scalar_str, &empty_attr);
17128 upb_handlers_setendstr(h, type_field, scalar_endstr, &empty_attr);
17129
17130 /* This is not the full and correct JSON encoding for the Any value field. It
17131 * requires further processing by the wrapper code based on the type URL.
17132 */
17133 upb_handlers_setstartstr(h, value_field, scalar_startstr_onlykey,
17134 &value_name_attr);
17135
17136 UPB_UNUSED(closure);
17137}
17138
Paul Yangc4f2a922019-01-17 10:18:43 -080017139/* Set up handlers for a fieldmask submessage. */
17140void printer_sethandlers_fieldmask(const void *closure, upb_handlers *h) {
17141 const upb_msgdef *md = upb_handlers_msgdef(h);
17142 const upb_fielddef* f = upb_msgdef_itof(md, 1);
17143
17144 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17145
17146 upb_handlers_setstartseq(h, f, startseq_fieldmask, &empty_attr);
17147 upb_handlers_setendseq(h, f, endseq_fieldmask, &empty_attr);
17148
Paul Yang7f42d6d2019-01-22 15:35:12 -080017149 upb_handlers_setstartmsg(h, printer_startmsg_fieldmask, &empty_attr);
17150 upb_handlers_setendmsg(h, printer_endmsg_fieldmask, &empty_attr);
Paul Yangc4f2a922019-01-17 10:18:43 -080017151
17152 upb_handlers_setstartstr(h, f, repeated_startstr_fieldmask, &empty_attr);
17153 upb_handlers_setstring(h, f, repeated_str_fieldmask, &empty_attr);
17154
17155 UPB_UNUSED(closure);
17156}
17157
Paul Yang9bda1f12018-09-22 18:57:43 -070017158/* Set up handlers for a duration submessage. */
17159void printer_sethandlers_duration(const void *closure, upb_handlers *h) {
17160 const upb_msgdef *md = upb_handlers_msgdef(h);
17161
17162 const upb_fielddef* seconds_field =
17163 upb_msgdef_itof(md, UPB_DURATION_SECONDS);
17164 const upb_fielddef* nanos_field =
17165 upb_msgdef_itof(md, UPB_DURATION_NANOS);
17166
17167 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17168
17169 upb_handlers_setstartmsg(h, printer_startdurationmsg, &empty_attr);
17170 upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
17171 upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
17172 upb_handlers_setendmsg(h, printer_enddurationmsg, &empty_attr);
17173
17174 UPB_UNUSED(closure);
17175}
17176
17177/* Set up handlers for a timestamp submessage. Instead of printing fields
17178 * separately, the json representation of timestamp follows RFC 3339 */
17179void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) {
17180 const upb_msgdef *md = upb_handlers_msgdef(h);
17181
17182 const upb_fielddef* seconds_field =
17183 upb_msgdef_itof(md, UPB_TIMESTAMP_SECONDS);
17184 const upb_fielddef* nanos_field =
17185 upb_msgdef_itof(md, UPB_TIMESTAMP_NANOS);
17186
17187 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17188
17189 upb_handlers_setstartmsg(h, printer_starttimestampmsg, &empty_attr);
17190 upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr);
17191 upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr);
17192 upb_handlers_setendmsg(h, printer_endtimestampmsg, &empty_attr);
17193
17194 UPB_UNUSED(closure);
17195}
17196
17197void printer_sethandlers_value(const void *closure, upb_handlers *h) {
17198 const upb_msgdef *md = upb_handlers_msgdef(h);
17199 upb_msg_field_iter i;
17200
17201 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17202
17203 upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
17204 upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
17205
17206 upb_msg_field_begin(&i, md);
17207 for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
17208 const upb_fielddef *f = upb_msg_iter_field(&i);
17209
17210 switch (upb_fielddef_type(f)) {
17211 case UPB_TYPE_ENUM:
17212 upb_handlers_setint32(h, f, putnull, &empty_attr);
17213 break;
17214 case UPB_TYPE_DOUBLE:
17215 upb_handlers_setdouble(h, f, putdouble, &empty_attr);
17216 break;
17217 case UPB_TYPE_STRING:
17218 upb_handlers_setstartstr(h, f, scalar_startstr_nokey, &empty_attr);
17219 upb_handlers_setstring(h, f, scalar_str, &empty_attr);
17220 upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
17221 break;
17222 case UPB_TYPE_BOOL:
17223 upb_handlers_setbool(h, f, putbool, &empty_attr);
17224 break;
17225 case UPB_TYPE_MESSAGE:
17226 break;
17227 default:
17228 UPB_ASSERT(false);
17229 break;
17230 }
17231 }
17232
17233 UPB_UNUSED(closure);
17234}
17235
17236#define WRAPPER_SETHANDLERS(wrapper, type, putmethod) \
17237void printer_sethandlers_##wrapper(const void *closure, upb_handlers *h) { \
17238 const upb_msgdef *md = upb_handlers_msgdef(h); \
17239 const upb_fielddef* f = upb_msgdef_itof(md, 1); \
17240 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER; \
17241 upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); \
17242 upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); \
17243 upb_handlers_set##type(h, f, putmethod, &empty_attr); \
17244 UPB_UNUSED(closure); \
17245}
17246
17247WRAPPER_SETHANDLERS(doublevalue, double, putdouble)
17248WRAPPER_SETHANDLERS(floatvalue, float, putfloat)
17249WRAPPER_SETHANDLERS(int64value, int64, putint64_t)
17250WRAPPER_SETHANDLERS(uint64value, uint64, putuint64_t)
17251WRAPPER_SETHANDLERS(int32value, int32, putint32_t)
17252WRAPPER_SETHANDLERS(uint32value, uint32, putuint32_t)
17253WRAPPER_SETHANDLERS(boolvalue, bool, putbool)
17254WRAPPER_SETHANDLERS(stringvalue, string, putstr_nokey)
17255WRAPPER_SETHANDLERS(bytesvalue, string, putbytes)
17256
17257#undef WRAPPER_SETHANDLERS
17258
17259void printer_sethandlers_listvalue(const void *closure, upb_handlers *h) {
17260 const upb_msgdef *md = upb_handlers_msgdef(h);
17261 const upb_fielddef* f = upb_msgdef_itof(md, 1);
17262
17263 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17264
17265 upb_handlers_setstartseq(h, f, startseq_nokey, &empty_attr);
17266 upb_handlers_setendseq(h, f, endseq, &empty_attr);
17267
17268 upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
17269 upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
17270
17271 upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr);
17272
17273 UPB_UNUSED(closure);
17274}
17275
17276void printer_sethandlers_structvalue(const void *closure, upb_handlers *h) {
17277 const upb_msgdef *md = upb_handlers_msgdef(h);
17278 const upb_fielddef* f = upb_msgdef_itof(md, 1);
17279
17280 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17281
17282 upb_handlers_setstartseq(h, f, startmap_nokey, &empty_attr);
17283 upb_handlers_setendseq(h, f, endmap, &empty_attr);
17284
17285 upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
17286 upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
17287
17288 upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr);
17289
17290 UPB_UNUSED(closure);
17291}
17292
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017293void printer_sethandlers(const void *closure, upb_handlers *h) {
17294 const upb_msgdef *md = upb_handlers_msgdef(h);
17295 bool is_mapentry = upb_msgdef_mapentry(md);
17296 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
17297 upb_msg_field_iter i;
Paul Yange0e54662016-09-15 11:09:01 -070017298 const bool *preserve_fieldnames_ptr = closure;
17299 const bool preserve_fieldnames = *preserve_fieldnames_ptr;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017300
17301 if (is_mapentry) {
17302 /* mapentry messages are sufficiently different that we handle them
17303 * separately. */
Paul Yange0e54662016-09-15 11:09:01 -070017304 printer_sethandlers_mapentry(closure, preserve_fieldnames, h);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017305 return;
17306 }
17307
Paul Yang9bda1f12018-09-22 18:57:43 -070017308 switch (upb_msgdef_wellknowntype(md)) {
17309 case UPB_WELLKNOWN_UNSPECIFIED:
17310 break;
Paul Yang8faa7782018-12-26 10:36:09 -080017311 case UPB_WELLKNOWN_ANY:
17312 printer_sethandlers_any(closure, h);
17313 return;
Paul Yangc4f2a922019-01-17 10:18:43 -080017314 case UPB_WELLKNOWN_FIELDMASK:
17315 printer_sethandlers_fieldmask(closure, h);
17316 return;
Paul Yang9bda1f12018-09-22 18:57:43 -070017317 case UPB_WELLKNOWN_DURATION:
17318 printer_sethandlers_duration(closure, h);
17319 return;
17320 case UPB_WELLKNOWN_TIMESTAMP:
17321 printer_sethandlers_timestamp(closure, h);
17322 return;
17323 case UPB_WELLKNOWN_VALUE:
17324 printer_sethandlers_value(closure, h);
17325 return;
17326 case UPB_WELLKNOWN_LISTVALUE:
17327 printer_sethandlers_listvalue(closure, h);
17328 return;
17329 case UPB_WELLKNOWN_STRUCT:
17330 printer_sethandlers_structvalue(closure, h);
17331 return;
17332#define WRAPPER(wellknowntype, name) \
17333 case wellknowntype: \
17334 printer_sethandlers_##name(closure, h); \
17335 return; \
17336
17337 WRAPPER(UPB_WELLKNOWN_DOUBLEVALUE, doublevalue);
17338 WRAPPER(UPB_WELLKNOWN_FLOATVALUE, floatvalue);
17339 WRAPPER(UPB_WELLKNOWN_INT64VALUE, int64value);
17340 WRAPPER(UPB_WELLKNOWN_UINT64VALUE, uint64value);
17341 WRAPPER(UPB_WELLKNOWN_INT32VALUE, int32value);
17342 WRAPPER(UPB_WELLKNOWN_UINT32VALUE, uint32value);
17343 WRAPPER(UPB_WELLKNOWN_BOOLVALUE, boolvalue);
17344 WRAPPER(UPB_WELLKNOWN_STRINGVALUE, stringvalue);
17345 WRAPPER(UPB_WELLKNOWN_BYTESVALUE, bytesvalue);
17346
17347#undef WRAPPER
17348 }
17349
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017350 upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
17351 upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
17352
17353#define TYPE(type, name, ctype) \
17354 case type: \
17355 if (upb_fielddef_isseq(f)) { \
17356 upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
17357 } else { \
17358 upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
17359 } \
17360 break;
17361
17362 upb_msg_field_begin(&i, md);
17363 for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
17364 const upb_fielddef *f = upb_msg_iter_field(&i);
17365
17366 upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
Paul Yange0e54662016-09-15 11:09:01 -070017367 upb_handlerattr_sethandlerdata(&name_attr,
17368 newstrpc(h, f, preserve_fieldnames));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017369
17370 if (upb_fielddef_ismap(f)) {
17371 upb_handlers_setstartseq(h, f, startmap, &name_attr);
17372 upb_handlers_setendseq(h, f, endmap, &name_attr);
17373 } else if (upb_fielddef_isseq(f)) {
17374 upb_handlers_setstartseq(h, f, startseq, &name_attr);
17375 upb_handlers_setendseq(h, f, endseq, &empty_attr);
17376 }
17377
17378 switch (upb_fielddef_type(f)) {
17379 TYPE(UPB_TYPE_FLOAT, float, float);
17380 TYPE(UPB_TYPE_DOUBLE, double, double);
17381 TYPE(UPB_TYPE_BOOL, bool, bool);
17382 TYPE(UPB_TYPE_INT32, int32, int32_t);
17383 TYPE(UPB_TYPE_UINT32, uint32, uint32_t);
17384 TYPE(UPB_TYPE_INT64, int64, int64_t);
17385 TYPE(UPB_TYPE_UINT64, uint64, uint64_t);
17386 case UPB_TYPE_ENUM: {
17387 /* For now, we always emit symbolic names for enums. We may want an
17388 * option later to control this behavior, but we will wait for a real
17389 * need first. */
17390 upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
Paul Yange0e54662016-09-15 11:09:01 -070017391 set_enum_hd(h, f, preserve_fieldnames, &enum_attr);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017392
17393 if (upb_fielddef_isseq(f)) {
17394 upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
17395 } else {
17396 upb_handlers_setint32(h, f, scalar_enum, &enum_attr);
17397 }
17398
17399 upb_handlerattr_uninit(&enum_attr);
17400 break;
17401 }
17402 case UPB_TYPE_STRING:
17403 if (upb_fielddef_isseq(f)) {
17404 upb_handlers_setstartstr(h, f, repeated_startstr, &empty_attr);
17405 upb_handlers_setstring(h, f, repeated_str, &empty_attr);
17406 upb_handlers_setendstr(h, f, repeated_endstr, &empty_attr);
17407 } else {
17408 upb_handlers_setstartstr(h, f, scalar_startstr, &name_attr);
17409 upb_handlers_setstring(h, f, scalar_str, &empty_attr);
17410 upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
17411 }
17412 break;
17413 case UPB_TYPE_BYTES:
17414 /* XXX: this doesn't support strings that span buffers yet. The base64
17415 * encoder will need to be made resumable for this to work properly. */
17416 if (upb_fielddef_isseq(f)) {
17417 upb_handlers_setstring(h, f, repeated_bytes, &empty_attr);
17418 } else {
17419 upb_handlers_setstring(h, f, scalar_bytes, &name_attr);
17420 }
17421 break;
17422 case UPB_TYPE_MESSAGE:
17423 if (upb_fielddef_isseq(f)) {
17424 upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &name_attr);
17425 } else {
17426 upb_handlers_setstartsubmsg(h, f, scalar_startsubmsg, &name_attr);
17427 }
17428 break;
17429 }
17430
17431 upb_handlerattr_uninit(&name_attr);
17432 }
17433
17434 upb_handlerattr_uninit(&empty_attr);
17435#undef TYPE
17436}
17437
17438static void json_printer_reset(upb_json_printer *p) {
17439 p->depth_ = 0;
17440}
17441
17442
17443/* Public API *****************************************************************/
17444
17445upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h,
17446 upb_bytessink *output) {
17447#ifndef NDEBUG
17448 size_t size_before = upb_env_bytesallocated(e);
17449#endif
17450
17451 upb_json_printer *p = upb_env_malloc(e, sizeof(upb_json_printer));
17452 if (!p) return NULL;
17453
17454 p->output_ = output;
17455 json_printer_reset(p);
17456 upb_sink_reset(&p->input_, h, p);
Paul Yang9bda1f12018-09-22 18:57:43 -070017457 p->seconds = 0;
17458 p->nanos = 0;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017459
17460 /* If this fails, increase the value in printer.h. */
Paul Yange0e54662016-09-15 11:09:01 -070017461 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
17462 UPB_JSON_PRINTER_SIZE);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017463 return p;
17464}
17465
17466upb_sink *upb_json_printer_input(upb_json_printer *p) {
17467 return &p->input_;
17468}
17469
17470const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
Paul Yange0e54662016-09-15 11:09:01 -070017471 bool preserve_fieldnames,
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017472 const void *owner) {
Paul Yange0e54662016-09-15 11:09:01 -070017473 return upb_handlers_newfrozen(
17474 md, owner, printer_sethandlers, &preserve_fieldnames);
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070017475}
Paul Yang9bda1f12018-09-22 18:57:43 -070017476
17477#undef UPB_SIZE
17478#undef UPB_FIELD_AT
17479#undef UPB_READ_ONEOF
17480#undef UPB_WRITE_ONEOF