blob: e01f3bfd6e8f229958e5a950c983e2d94aee5df3 [file] [log] [blame]
Austin Schuh40c16522018-10-28 20:27:54 -07001// Amalgamated source file
2#include "upb.h"
3/* This file was generated by upbc (the upb compiler) from the input
4 * file:
5 *
6 * google/protobuf/descriptor.proto
7 *
8 * Do not edit -- your changes will be discarded when the file is
9 * regenerated. */
10
11#include <stddef.h>
12
13
14struct google_protobuf_FileDescriptorSet {
15 upb_array* file;
16};
17
18static const upb_msglayout_msginit_v1 *const google_protobuf_FileDescriptorSet_submsgs[1] = {
19 &google_protobuf_FileDescriptorProto_msginit,
20};
21
22static const upb_msglayout_fieldinit_v1 google_protobuf_FileDescriptorSet__fields[1] = {
23 {1, offsetof(google_protobuf_FileDescriptorSet, file), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
24};
25
26const upb_msglayout_msginit_v1 google_protobuf_FileDescriptorSet_msginit = {
27 &google_protobuf_FileDescriptorSet_submsgs[0],
28 &google_protobuf_FileDescriptorSet__fields[0],
29 NULL,
30 NULL, /* TODO. default_msg */
31 UPB_ALIGNED_SIZEOF(google_protobuf_FileDescriptorSet), 1, 0, false, true
32};
33
34google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_env *env) {
35 google_protobuf_FileDescriptorSet *msg = upb_env_malloc(env, sizeof(*msg));
36 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
37 return msg;
38}
39google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parsenew(upb_stringview buf, upb_env *env) {
40 google_protobuf_FileDescriptorSet *msg = google_protobuf_FileDescriptorSet_new(env);
41 if (upb_decode(buf, msg, &google_protobuf_FileDescriptorSet_msginit, env)) {
42 return msg;
43 } else {
44 return NULL;
45 }
46}
47char *google_protobuf_FileDescriptorSet_serialize(google_protobuf_FileDescriptorSet *msg, upb_env *env, size_t *size) {
48 return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, env, size);
49}
50const upb_array* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg) {
51 return msg->file;
52}
53void google_protobuf_FileDescriptorSet_set_file(google_protobuf_FileDescriptorSet *msg, upb_array* value) {
54 msg->file = value;
55}
56struct google_protobuf_FileDescriptorProto {
57 upb_stringview name;
58 upb_stringview package;
59 upb_stringview syntax;
60 google_protobuf_FileOptions* options;
61 google_protobuf_SourceCodeInfo* source_code_info;
62 upb_array* dependency;
63 upb_array* message_type;
64 upb_array* enum_type;
65 upb_array* service;
66 upb_array* extension;
67 upb_array* public_dependency;
68 upb_array* weak_dependency;
69};
70
71static const upb_msglayout_msginit_v1 *const google_protobuf_FileDescriptorProto_submsgs[6] = {
72 &google_protobuf_DescriptorProto_msginit,
73 &google_protobuf_EnumDescriptorProto_msginit,
74 &google_protobuf_FieldDescriptorProto_msginit,
75 &google_protobuf_FileOptions_msginit,
76 &google_protobuf_ServiceDescriptorProto_msginit,
77 &google_protobuf_SourceCodeInfo_msginit,
78};
79
80static const upb_msglayout_fieldinit_v1 google_protobuf_FileDescriptorProto__fields[12] = {
81 {1, offsetof(google_protobuf_FileDescriptorProto, name), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
82 {2, offsetof(google_protobuf_FileDescriptorProto, package), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
83 {3, offsetof(google_protobuf_FileDescriptorProto, dependency), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 3},
84 {4, offsetof(google_protobuf_FileDescriptorProto, message_type), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
85 {5, offsetof(google_protobuf_FileDescriptorProto, enum_type), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 1, 11, 3},
86 {6, offsetof(google_protobuf_FileDescriptorProto, service), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 4, 11, 3},
87 {7, offsetof(google_protobuf_FileDescriptorProto, extension), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 2, 11, 3},
88 {8, offsetof(google_protobuf_FileDescriptorProto, options), 3, UPB_NOT_IN_ONEOF, 3, 11, 1},
89 {9, offsetof(google_protobuf_FileDescriptorProto, source_code_info), 4, UPB_NOT_IN_ONEOF, 5, 11, 1},
90 {10, offsetof(google_protobuf_FileDescriptorProto, public_dependency), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 3},
91 {11, offsetof(google_protobuf_FileDescriptorProto, weak_dependency), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 3},
92 {12, offsetof(google_protobuf_FileDescriptorProto, syntax), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
93};
94
95const upb_msglayout_msginit_v1 google_protobuf_FileDescriptorProto_msginit = {
96 &google_protobuf_FileDescriptorProto_submsgs[0],
97 &google_protobuf_FileDescriptorProto__fields[0],
98 NULL,
99 NULL, /* TODO. default_msg */
100 UPB_ALIGNED_SIZEOF(google_protobuf_FileDescriptorProto), 12, 0, false, true
101};
102
103google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_env *env) {
104 google_protobuf_FileDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
105 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
106 return msg;
107}
108google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
109 google_protobuf_FileDescriptorProto *msg = google_protobuf_FileDescriptorProto_new(env);
110 if (upb_decode(buf, msg, &google_protobuf_FileDescriptorProto_msginit, env)) {
111 return msg;
112 } else {
113 return NULL;
114 }
115}
116char *google_protobuf_FileDescriptorProto_serialize(google_protobuf_FileDescriptorProto *msg, upb_env *env, size_t *size) {
117 return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, env, size);
118}
119upb_stringview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) {
120 return msg->name;
121}
122void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_stringview value) {
123 msg->name = value;
124}
125upb_stringview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) {
126 return msg->package;
127}
128void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_stringview value) {
129 msg->package = value;
130}
131const upb_array* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg) {
132 return msg->dependency;
133}
134void google_protobuf_FileDescriptorProto_set_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
135 msg->dependency = value;
136}
137const upb_array* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg) {
138 return msg->message_type;
139}
140void google_protobuf_FileDescriptorProto_set_message_type(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
141 msg->message_type = value;
142}
143const upb_array* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg) {
144 return msg->enum_type;
145}
146void google_protobuf_FileDescriptorProto_set_enum_type(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
147 msg->enum_type = value;
148}
149const upb_array* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg) {
150 return msg->service;
151}
152void google_protobuf_FileDescriptorProto_set_service(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
153 msg->service = value;
154}
155const upb_array* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg) {
156 return msg->extension;
157}
158void google_protobuf_FileDescriptorProto_set_extension(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
159 msg->extension = value;
160}
161const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) {
162 return msg->options;
163}
164void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) {
165 msg->options = value;
166}
167const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) {
168 return msg->source_code_info;
169}
170void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) {
171 msg->source_code_info = value;
172}
173const upb_array* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg) {
174 return msg->public_dependency;
175}
176void google_protobuf_FileDescriptorProto_set_public_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
177 msg->public_dependency = value;
178}
179const upb_array* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg) {
180 return msg->weak_dependency;
181}
182void google_protobuf_FileDescriptorProto_set_weak_dependency(google_protobuf_FileDescriptorProto *msg, upb_array* value) {
183 msg->weak_dependency = value;
184}
185upb_stringview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) {
186 return msg->syntax;
187}
188void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_stringview value) {
189 msg->syntax = value;
190}
191struct google_protobuf_DescriptorProto {
192 upb_stringview name;
193 google_protobuf_MessageOptions* options;
194 upb_array* field;
195 upb_array* nested_type;
196 upb_array* enum_type;
197 upb_array* extension_range;
198 upb_array* extension;
199 upb_array* oneof_decl;
200 upb_array* reserved_range;
201 upb_array* reserved_name;
202};
203
204static const upb_msglayout_msginit_v1 *const google_protobuf_DescriptorProto_submsgs[8] = {
205 &google_protobuf_DescriptorProto_msginit,
206 &google_protobuf_DescriptorProto_ExtensionRange_msginit,
207 &google_protobuf_DescriptorProto_ReservedRange_msginit,
208 &google_protobuf_EnumDescriptorProto_msginit,
209 &google_protobuf_FieldDescriptorProto_msginit,
210 &google_protobuf_MessageOptions_msginit,
211 &google_protobuf_OneofDescriptorProto_msginit,
212};
213
214static const upb_msglayout_fieldinit_v1 google_protobuf_DescriptorProto__fields[10] = {
215 {1, offsetof(google_protobuf_DescriptorProto, name), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
216 {2, offsetof(google_protobuf_DescriptorProto, field), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 4, 11, 3},
217 {3, offsetof(google_protobuf_DescriptorProto, nested_type), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
218 {4, offsetof(google_protobuf_DescriptorProto, enum_type), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 3, 11, 3},
219 {5, offsetof(google_protobuf_DescriptorProto, extension_range), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 1, 11, 3},
220 {6, offsetof(google_protobuf_DescriptorProto, extension), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 4, 11, 3},
221 {7, offsetof(google_protobuf_DescriptorProto, options), 1, UPB_NOT_IN_ONEOF, 5, 11, 1},
222 {8, offsetof(google_protobuf_DescriptorProto, oneof_decl), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 6, 11, 3},
223 {9, offsetof(google_protobuf_DescriptorProto, reserved_range), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 2, 11, 3},
224 {10, offsetof(google_protobuf_DescriptorProto, reserved_name), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 3},
225};
226
227const upb_msglayout_msginit_v1 google_protobuf_DescriptorProto_msginit = {
228 &google_protobuf_DescriptorProto_submsgs[0],
229 &google_protobuf_DescriptorProto__fields[0],
230 NULL,
231 NULL, /* TODO. default_msg */
232 UPB_ALIGNED_SIZEOF(google_protobuf_DescriptorProto), 10, 0, false, true
233};
234
235google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_env *env) {
236 google_protobuf_DescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
237 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
238 return msg;
239}
240google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
241 google_protobuf_DescriptorProto *msg = google_protobuf_DescriptorProto_new(env);
242 if (upb_decode(buf, msg, &google_protobuf_DescriptorProto_msginit, env)) {
243 return msg;
244 } else {
245 return NULL;
246 }
247}
248char *google_protobuf_DescriptorProto_serialize(google_protobuf_DescriptorProto *msg, upb_env *env, size_t *size) {
249 return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, env, size);
250}
251upb_stringview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) {
252 return msg->name;
253}
254void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_stringview value) {
255 msg->name = value;
256}
257const upb_array* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg) {
258 return msg->field;
259}
260void google_protobuf_DescriptorProto_set_field(google_protobuf_DescriptorProto *msg, upb_array* value) {
261 msg->field = value;
262}
263const upb_array* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg) {
264 return msg->nested_type;
265}
266void google_protobuf_DescriptorProto_set_nested_type(google_protobuf_DescriptorProto *msg, upb_array* value) {
267 msg->nested_type = value;
268}
269const upb_array* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg) {
270 return msg->enum_type;
271}
272void google_protobuf_DescriptorProto_set_enum_type(google_protobuf_DescriptorProto *msg, upb_array* value) {
273 msg->enum_type = value;
274}
275const upb_array* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg) {
276 return msg->extension_range;
277}
278void google_protobuf_DescriptorProto_set_extension_range(google_protobuf_DescriptorProto *msg, upb_array* value) {
279 msg->extension_range = value;
280}
281const upb_array* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg) {
282 return msg->extension;
283}
284void google_protobuf_DescriptorProto_set_extension(google_protobuf_DescriptorProto *msg, upb_array* value) {
285 msg->extension = value;
286}
287const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) {
288 return msg->options;
289}
290void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) {
291 msg->options = value;
292}
293const upb_array* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg) {
294 return msg->oneof_decl;
295}
296void google_protobuf_DescriptorProto_set_oneof_decl(google_protobuf_DescriptorProto *msg, upb_array* value) {
297 msg->oneof_decl = value;
298}
299const upb_array* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg) {
300 return msg->reserved_range;
301}
302void google_protobuf_DescriptorProto_set_reserved_range(google_protobuf_DescriptorProto *msg, upb_array* value) {
303 msg->reserved_range = value;
304}
305const upb_array* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg) {
306 return msg->reserved_name;
307}
308void google_protobuf_DescriptorProto_set_reserved_name(google_protobuf_DescriptorProto *msg, upb_array* value) {
309 msg->reserved_name = value;
310}
311struct google_protobuf_DescriptorProto_ExtensionRange {
312 int32_t start;
313 int32_t end;
314 google_protobuf_ExtensionRangeOptions* options;
315};
316
317static const upb_msglayout_msginit_v1 *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
318 &google_protobuf_ExtensionRangeOptions_msginit,
319};
320
321static const upb_msglayout_fieldinit_v1 google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
322 {1, offsetof(google_protobuf_DescriptorProto_ExtensionRange, start), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
323 {2, offsetof(google_protobuf_DescriptorProto_ExtensionRange, end), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
324 {3, offsetof(google_protobuf_DescriptorProto_ExtensionRange, options), 2, UPB_NOT_IN_ONEOF, 0, 11, 1},
325};
326
327const upb_msglayout_msginit_v1 google_protobuf_DescriptorProto_ExtensionRange_msginit = {
328 &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
329 &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
330 NULL,
331 NULL, /* TODO. default_msg */
332 UPB_ALIGNED_SIZEOF(google_protobuf_DescriptorProto_ExtensionRange), 3, 0, false, true
333};
334
335google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_env *env) {
336 google_protobuf_DescriptorProto_ExtensionRange *msg = upb_env_malloc(env, sizeof(*msg));
337 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
338 return msg;
339}
340google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parsenew(upb_stringview buf, upb_env *env) {
341 google_protobuf_DescriptorProto_ExtensionRange *msg = google_protobuf_DescriptorProto_ExtensionRange_new(env);
342 if (upb_decode(buf, msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, env)) {
343 return msg;
344 } else {
345 return NULL;
346 }
347}
348char *google_protobuf_DescriptorProto_ExtensionRange_serialize(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_env *env, size_t *size) {
349 return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, env, size);
350}
351int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) {
352 return msg->start;
353}
354void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) {
355 msg->start = value;
356}
357int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) {
358 return msg->end;
359}
360void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) {
361 msg->end = value;
362}
363const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) {
364 return msg->options;
365}
366void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) {
367 msg->options = value;
368}
369struct google_protobuf_DescriptorProto_ReservedRange {
370 int32_t start;
371 int32_t end;
372};
373
374static const upb_msglayout_fieldinit_v1 google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
375 {1, offsetof(google_protobuf_DescriptorProto_ReservedRange, start), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
376 {2, offsetof(google_protobuf_DescriptorProto_ReservedRange, end), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
377};
378
379const upb_msglayout_msginit_v1 google_protobuf_DescriptorProto_ReservedRange_msginit = {
380 NULL,
381 &google_protobuf_DescriptorProto_ReservedRange__fields[0],
382 NULL,
383 NULL, /* TODO. default_msg */
384 UPB_ALIGNED_SIZEOF(google_protobuf_DescriptorProto_ReservedRange), 2, 0, false, true
385};
386
387google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_env *env) {
388 google_protobuf_DescriptorProto_ReservedRange *msg = upb_env_malloc(env, sizeof(*msg));
389 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
390 return msg;
391}
392google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parsenew(upb_stringview buf, upb_env *env) {
393 google_protobuf_DescriptorProto_ReservedRange *msg = google_protobuf_DescriptorProto_ReservedRange_new(env);
394 if (upb_decode(buf, msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, env)) {
395 return msg;
396 } else {
397 return NULL;
398 }
399}
400char *google_protobuf_DescriptorProto_ReservedRange_serialize(google_protobuf_DescriptorProto_ReservedRange *msg, upb_env *env, size_t *size) {
401 return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, env, size);
402}
403int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) {
404 return msg->start;
405}
406void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) {
407 msg->start = value;
408}
409int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) {
410 return msg->end;
411}
412void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) {
413 msg->end = value;
414}
415struct google_protobuf_ExtensionRangeOptions {
416 upb_array* uninterpreted_option;
417};
418
419static const upb_msglayout_msginit_v1 *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
420 &google_protobuf_UninterpretedOption_msginit,
421};
422
423static const upb_msglayout_fieldinit_v1 google_protobuf_ExtensionRangeOptions__fields[1] = {
424 {999, offsetof(google_protobuf_ExtensionRangeOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
425};
426
427const upb_msglayout_msginit_v1 google_protobuf_ExtensionRangeOptions_msginit = {
428 &google_protobuf_ExtensionRangeOptions_submsgs[0],
429 &google_protobuf_ExtensionRangeOptions__fields[0],
430 NULL,
431 NULL, /* TODO. default_msg */
432 UPB_ALIGNED_SIZEOF(google_protobuf_ExtensionRangeOptions), 1, 0, false, true
433};
434
435google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_env *env) {
436 google_protobuf_ExtensionRangeOptions *msg = upb_env_malloc(env, sizeof(*msg));
437 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
438 return msg;
439}
440google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parsenew(upb_stringview buf, upb_env *env) {
441 google_protobuf_ExtensionRangeOptions *msg = google_protobuf_ExtensionRangeOptions_new(env);
442 if (upb_decode(buf, msg, &google_protobuf_ExtensionRangeOptions_msginit, env)) {
443 return msg;
444 } else {
445 return NULL;
446 }
447}
448char *google_protobuf_ExtensionRangeOptions_serialize(google_protobuf_ExtensionRangeOptions *msg, upb_env *env, size_t *size) {
449 return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, env, size);
450}
451const upb_array* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg) {
452 return msg->uninterpreted_option;
453}
454void google_protobuf_ExtensionRangeOptions_set_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_array* value) {
455 msg->uninterpreted_option = value;
456}
457struct google_protobuf_FieldDescriptorProto {
458 google_protobuf_FieldDescriptorProto_Label label;
459 google_protobuf_FieldDescriptorProto_Type type;
460 int32_t number;
461 int32_t oneof_index;
462 upb_stringview name;
463 upb_stringview extendee;
464 upb_stringview type_name;
465 upb_stringview default_value;
466 upb_stringview json_name;
467 google_protobuf_FieldOptions* options;
468};
469
470static const upb_msglayout_msginit_v1 *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
471 &google_protobuf_FieldOptions_msginit,
472};
473
474static const upb_msglayout_fieldinit_v1 google_protobuf_FieldDescriptorProto__fields[10] = {
475 {1, offsetof(google_protobuf_FieldDescriptorProto, name), 4, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
476 {2, offsetof(google_protobuf_FieldDescriptorProto, extendee), 5, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
477 {3, offsetof(google_protobuf_FieldDescriptorProto, number), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
478 {4, offsetof(google_protobuf_FieldDescriptorProto, label), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
479 {5, offsetof(google_protobuf_FieldDescriptorProto, type), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
480 {6, offsetof(google_protobuf_FieldDescriptorProto, type_name), 6, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
481 {7, offsetof(google_protobuf_FieldDescriptorProto, default_value), 7, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
482 {8, offsetof(google_protobuf_FieldDescriptorProto, options), 9, UPB_NOT_IN_ONEOF, 0, 11, 1},
483 {9, offsetof(google_protobuf_FieldDescriptorProto, oneof_index), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
484 {10, offsetof(google_protobuf_FieldDescriptorProto, json_name), 8, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
485};
486
487const upb_msglayout_msginit_v1 google_protobuf_FieldDescriptorProto_msginit = {
488 &google_protobuf_FieldDescriptorProto_submsgs[0],
489 &google_protobuf_FieldDescriptorProto__fields[0],
490 NULL,
491 NULL, /* TODO. default_msg */
492 UPB_ALIGNED_SIZEOF(google_protobuf_FieldDescriptorProto), 10, 0, false, true
493};
494
495google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_env *env) {
496 google_protobuf_FieldDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
497 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
498 return msg;
499}
500google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
501 google_protobuf_FieldDescriptorProto *msg = google_protobuf_FieldDescriptorProto_new(env);
502 if (upb_decode(buf, msg, &google_protobuf_FieldDescriptorProto_msginit, env)) {
503 return msg;
504 } else {
505 return NULL;
506 }
507}
508char *google_protobuf_FieldDescriptorProto_serialize(google_protobuf_FieldDescriptorProto *msg, upb_env *env, size_t *size) {
509 return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, env, size);
510}
511upb_stringview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) {
512 return msg->name;
513}
514void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) {
515 msg->name = value;
516}
517upb_stringview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) {
518 return msg->extendee;
519}
520void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) {
521 msg->extendee = value;
522}
523int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) {
524 return msg->number;
525}
526void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
527 msg->number = value;
528}
529google_protobuf_FieldDescriptorProto_Label google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) {
530 return msg->label;
531}
532void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Label value) {
533 msg->label = value;
534}
535google_protobuf_FieldDescriptorProto_Type google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) {
536 return msg->type;
537}
538void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldDescriptorProto_Type value) {
539 msg->type = value;
540}
541upb_stringview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) {
542 return msg->type_name;
543}
544void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) {
545 msg->type_name = value;
546}
547upb_stringview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) {
548 return msg->default_value;
549}
550void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) {
551 msg->default_value = value;
552}
553const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) {
554 return msg->options;
555}
556void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
557 msg->options = value;
558}
559int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) {
560 return msg->oneof_index;
561}
562void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
563 msg->oneof_index = value;
564}
565upb_stringview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) {
566 return msg->json_name;
567}
568void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_stringview value) {
569 msg->json_name = value;
570}
571struct google_protobuf_OneofDescriptorProto {
572 upb_stringview name;
573 google_protobuf_OneofOptions* options;
574};
575
576static const upb_msglayout_msginit_v1 *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
577 &google_protobuf_OneofOptions_msginit,
578};
579
580static const upb_msglayout_fieldinit_v1 google_protobuf_OneofDescriptorProto__fields[2] = {
581 {1, offsetof(google_protobuf_OneofDescriptorProto, name), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
582 {2, offsetof(google_protobuf_OneofDescriptorProto, options), 1, UPB_NOT_IN_ONEOF, 0, 11, 1},
583};
584
585const upb_msglayout_msginit_v1 google_protobuf_OneofDescriptorProto_msginit = {
586 &google_protobuf_OneofDescriptorProto_submsgs[0],
587 &google_protobuf_OneofDescriptorProto__fields[0],
588 NULL,
589 NULL, /* TODO. default_msg */
590 UPB_ALIGNED_SIZEOF(google_protobuf_OneofDescriptorProto), 2, 0, false, true
591};
592
593google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_env *env) {
594 google_protobuf_OneofDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
595 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
596 return msg;
597}
598google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
599 google_protobuf_OneofDescriptorProto *msg = google_protobuf_OneofDescriptorProto_new(env);
600 if (upb_decode(buf, msg, &google_protobuf_OneofDescriptorProto_msginit, env)) {
601 return msg;
602 } else {
603 return NULL;
604 }
605}
606char *google_protobuf_OneofDescriptorProto_serialize(google_protobuf_OneofDescriptorProto *msg, upb_env *env, size_t *size) {
607 return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, env, size);
608}
609upb_stringview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) {
610 return msg->name;
611}
612void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_stringview value) {
613 msg->name = value;
614}
615const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) {
616 return msg->options;
617}
618void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) {
619 msg->options = value;
620}
621struct google_protobuf_EnumDescriptorProto {
622 upb_stringview name;
623 google_protobuf_EnumOptions* options;
624 upb_array* value;
625 upb_array* reserved_range;
626 upb_array* reserved_name;
627};
628
629static const upb_msglayout_msginit_v1 *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
630 &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
631 &google_protobuf_EnumOptions_msginit,
632 &google_protobuf_EnumValueDescriptorProto_msginit,
633};
634
635static const upb_msglayout_fieldinit_v1 google_protobuf_EnumDescriptorProto__fields[5] = {
636 {1, offsetof(google_protobuf_EnumDescriptorProto, name), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
637 {2, offsetof(google_protobuf_EnumDescriptorProto, value), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 2, 11, 3},
638 {3, offsetof(google_protobuf_EnumDescriptorProto, options), 1, UPB_NOT_IN_ONEOF, 1, 11, 1},
639 {4, offsetof(google_protobuf_EnumDescriptorProto, reserved_range), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
640 {5, offsetof(google_protobuf_EnumDescriptorProto, reserved_name), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 3},
641};
642
643const upb_msglayout_msginit_v1 google_protobuf_EnumDescriptorProto_msginit = {
644 &google_protobuf_EnumDescriptorProto_submsgs[0],
645 &google_protobuf_EnumDescriptorProto__fields[0],
646 NULL,
647 NULL, /* TODO. default_msg */
648 UPB_ALIGNED_SIZEOF(google_protobuf_EnumDescriptorProto), 5, 0, false, true
649};
650
651google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_env *env) {
652 google_protobuf_EnumDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
653 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
654 return msg;
655}
656google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
657 google_protobuf_EnumDescriptorProto *msg = google_protobuf_EnumDescriptorProto_new(env);
658 if (upb_decode(buf, msg, &google_protobuf_EnumDescriptorProto_msginit, env)) {
659 return msg;
660 } else {
661 return NULL;
662 }
663}
664char *google_protobuf_EnumDescriptorProto_serialize(google_protobuf_EnumDescriptorProto *msg, upb_env *env, size_t *size) {
665 return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, env, size);
666}
667upb_stringview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) {
668 return msg->name;
669}
670void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_stringview value) {
671 msg->name = value;
672}
673const upb_array* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg) {
674 return msg->value;
675}
676void google_protobuf_EnumDescriptorProto_set_value(google_protobuf_EnumDescriptorProto *msg, upb_array* value) {
677 msg->value = value;
678}
679const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) {
680 return msg->options;
681}
682void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) {
683 msg->options = value;
684}
685const upb_array* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg) {
686 return msg->reserved_range;
687}
688void google_protobuf_EnumDescriptorProto_set_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_array* value) {
689 msg->reserved_range = value;
690}
691const upb_array* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg) {
692 return msg->reserved_name;
693}
694void google_protobuf_EnumDescriptorProto_set_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_array* value) {
695 msg->reserved_name = value;
696}
697struct google_protobuf_EnumDescriptorProto_EnumReservedRange {
698 int32_t start;
699 int32_t end;
700};
701
702static const upb_msglayout_fieldinit_v1 google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
703 {1, offsetof(google_protobuf_EnumDescriptorProto_EnumReservedRange, start), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
704 {2, offsetof(google_protobuf_EnumDescriptorProto_EnumReservedRange, end), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
705};
706
707const upb_msglayout_msginit_v1 google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
708 NULL,
709 &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
710 NULL,
711 NULL, /* TODO. default_msg */
712 UPB_ALIGNED_SIZEOF(google_protobuf_EnumDescriptorProto_EnumReservedRange), 2, 0, false, true
713};
714
715google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_env *env) {
716 google_protobuf_EnumDescriptorProto_EnumReservedRange *msg = upb_env_malloc(env, sizeof(*msg));
717 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
718 return msg;
719}
720google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parsenew(upb_stringview buf, upb_env *env) {
721 google_protobuf_EnumDescriptorProto_EnumReservedRange *msg = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(env);
722 if (upb_decode(buf, msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, env)) {
723 return msg;
724 } else {
725 return NULL;
726 }
727}
728char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_env *env, size_t *size) {
729 return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, env, size);
730}
731int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) {
732 return msg->start;
733}
734void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) {
735 msg->start = value;
736}
737int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) {
738 return msg->end;
739}
740void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) {
741 msg->end = value;
742}
743struct google_protobuf_EnumValueDescriptorProto {
744 int32_t number;
745 upb_stringview name;
746 google_protobuf_EnumValueOptions* options;
747};
748
749static const upb_msglayout_msginit_v1 *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
750 &google_protobuf_EnumValueOptions_msginit,
751};
752
753static const upb_msglayout_fieldinit_v1 google_protobuf_EnumValueDescriptorProto__fields[3] = {
754 {1, offsetof(google_protobuf_EnumValueDescriptorProto, name), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
755 {2, offsetof(google_protobuf_EnumValueDescriptorProto, number), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
756 {3, offsetof(google_protobuf_EnumValueDescriptorProto, options), 2, UPB_NOT_IN_ONEOF, 0, 11, 1},
757};
758
759const upb_msglayout_msginit_v1 google_protobuf_EnumValueDescriptorProto_msginit = {
760 &google_protobuf_EnumValueDescriptorProto_submsgs[0],
761 &google_protobuf_EnumValueDescriptorProto__fields[0],
762 NULL,
763 NULL, /* TODO. default_msg */
764 UPB_ALIGNED_SIZEOF(google_protobuf_EnumValueDescriptorProto), 3, 0, false, true
765};
766
767google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_env *env) {
768 google_protobuf_EnumValueDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
769 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
770 return msg;
771}
772google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
773 google_protobuf_EnumValueDescriptorProto *msg = google_protobuf_EnumValueDescriptorProto_new(env);
774 if (upb_decode(buf, msg, &google_protobuf_EnumValueDescriptorProto_msginit, env)) {
775 return msg;
776 } else {
777 return NULL;
778 }
779}
780char *google_protobuf_EnumValueDescriptorProto_serialize(google_protobuf_EnumValueDescriptorProto *msg, upb_env *env, size_t *size) {
781 return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, env, size);
782}
783upb_stringview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) {
784 return msg->name;
785}
786void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_stringview value) {
787 msg->name = value;
788}
789int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) {
790 return msg->number;
791}
792void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) {
793 msg->number = value;
794}
795const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) {
796 return msg->options;
797}
798void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) {
799 msg->options = value;
800}
801struct google_protobuf_ServiceDescriptorProto {
802 upb_stringview name;
803 google_protobuf_ServiceOptions* options;
804 upb_array* method;
805};
806
807static const upb_msglayout_msginit_v1 *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
808 &google_protobuf_MethodDescriptorProto_msginit,
809 &google_protobuf_ServiceOptions_msginit,
810};
811
812static const upb_msglayout_fieldinit_v1 google_protobuf_ServiceDescriptorProto__fields[3] = {
813 {1, offsetof(google_protobuf_ServiceDescriptorProto, name), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
814 {2, offsetof(google_protobuf_ServiceDescriptorProto, method), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
815 {3, offsetof(google_protobuf_ServiceDescriptorProto, options), 1, UPB_NOT_IN_ONEOF, 1, 11, 1},
816};
817
818const upb_msglayout_msginit_v1 google_protobuf_ServiceDescriptorProto_msginit = {
819 &google_protobuf_ServiceDescriptorProto_submsgs[0],
820 &google_protobuf_ServiceDescriptorProto__fields[0],
821 NULL,
822 NULL, /* TODO. default_msg */
823 UPB_ALIGNED_SIZEOF(google_protobuf_ServiceDescriptorProto), 3, 0, false, true
824};
825
826google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_env *env) {
827 google_protobuf_ServiceDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
828 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
829 return msg;
830}
831google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
832 google_protobuf_ServiceDescriptorProto *msg = google_protobuf_ServiceDescriptorProto_new(env);
833 if (upb_decode(buf, msg, &google_protobuf_ServiceDescriptorProto_msginit, env)) {
834 return msg;
835 } else {
836 return NULL;
837 }
838}
839char *google_protobuf_ServiceDescriptorProto_serialize(google_protobuf_ServiceDescriptorProto *msg, upb_env *env, size_t *size) {
840 return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, env, size);
841}
842upb_stringview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) {
843 return msg->name;
844}
845void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_stringview value) {
846 msg->name = value;
847}
848const upb_array* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg) {
849 return msg->method;
850}
851void google_protobuf_ServiceDescriptorProto_set_method(google_protobuf_ServiceDescriptorProto *msg, upb_array* value) {
852 msg->method = value;
853}
854const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) {
855 return msg->options;
856}
857void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) {
858 msg->options = value;
859}
860struct google_protobuf_MethodDescriptorProto {
861 bool client_streaming;
862 bool server_streaming;
863 upb_stringview name;
864 upb_stringview input_type;
865 upb_stringview output_type;
866 google_protobuf_MethodOptions* options;
867};
868
869static const upb_msglayout_msginit_v1 *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
870 &google_protobuf_MethodOptions_msginit,
871};
872
873static const upb_msglayout_fieldinit_v1 google_protobuf_MethodDescriptorProto__fields[6] = {
874 {1, offsetof(google_protobuf_MethodDescriptorProto, name), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
875 {2, offsetof(google_protobuf_MethodDescriptorProto, input_type), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
876 {3, offsetof(google_protobuf_MethodDescriptorProto, output_type), 4, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
877 {4, offsetof(google_protobuf_MethodDescriptorProto, options), 5, UPB_NOT_IN_ONEOF, 0, 11, 1},
878 {5, offsetof(google_protobuf_MethodDescriptorProto, client_streaming), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
879 {6, offsetof(google_protobuf_MethodDescriptorProto, server_streaming), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
880};
881
882const upb_msglayout_msginit_v1 google_protobuf_MethodDescriptorProto_msginit = {
883 &google_protobuf_MethodDescriptorProto_submsgs[0],
884 &google_protobuf_MethodDescriptorProto__fields[0],
885 NULL,
886 NULL, /* TODO. default_msg */
887 UPB_ALIGNED_SIZEOF(google_protobuf_MethodDescriptorProto), 6, 0, false, true
888};
889
890google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_env *env) {
891 google_protobuf_MethodDescriptorProto *msg = upb_env_malloc(env, sizeof(*msg));
892 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
893 return msg;
894}
895google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parsenew(upb_stringview buf, upb_env *env) {
896 google_protobuf_MethodDescriptorProto *msg = google_protobuf_MethodDescriptorProto_new(env);
897 if (upb_decode(buf, msg, &google_protobuf_MethodDescriptorProto_msginit, env)) {
898 return msg;
899 } else {
900 return NULL;
901 }
902}
903char *google_protobuf_MethodDescriptorProto_serialize(google_protobuf_MethodDescriptorProto *msg, upb_env *env, size_t *size) {
904 return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, env, size);
905}
906upb_stringview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) {
907 return msg->name;
908}
909void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) {
910 msg->name = value;
911}
912upb_stringview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) {
913 return msg->input_type;
914}
915void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) {
916 msg->input_type = value;
917}
918upb_stringview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) {
919 return msg->output_type;
920}
921void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_stringview value) {
922 msg->output_type = value;
923}
924const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) {
925 return msg->options;
926}
927void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) {
928 msg->options = value;
929}
930bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) {
931 return msg->client_streaming;
932}
933void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
934 msg->client_streaming = value;
935}
936bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) {
937 return msg->server_streaming;
938}
939void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
940 msg->server_streaming = value;
941}
942struct google_protobuf_FileOptions {
943 google_protobuf_FileOptions_OptimizeMode optimize_for;
944 bool java_multiple_files;
945 bool cc_generic_services;
946 bool java_generic_services;
947 bool py_generic_services;
948 bool java_generate_equals_and_hash;
949 bool deprecated;
950 bool java_string_check_utf8;
951 bool cc_enable_arenas;
952 bool php_generic_services;
953 upb_stringview java_package;
954 upb_stringview java_outer_classname;
955 upb_stringview go_package;
956 upb_stringview objc_class_prefix;
957 upb_stringview csharp_namespace;
958 upb_stringview swift_prefix;
959 upb_stringview php_class_prefix;
960 upb_stringview php_namespace;
961 upb_array* uninterpreted_option;
962};
963
964static const upb_msglayout_msginit_v1 *const google_protobuf_FileOptions_submsgs[1] = {
965 &google_protobuf_UninterpretedOption_msginit,
966};
967
968static const upb_msglayout_fieldinit_v1 google_protobuf_FileOptions__fields[19] = {
969 {1, offsetof(google_protobuf_FileOptions, java_package), 10, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
970 {8, offsetof(google_protobuf_FileOptions, java_outer_classname), 11, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
971 {9, offsetof(google_protobuf_FileOptions, optimize_for), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
972 {10, offsetof(google_protobuf_FileOptions, java_multiple_files), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
973 {11, offsetof(google_protobuf_FileOptions, go_package), 12, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
974 {16, offsetof(google_protobuf_FileOptions, cc_generic_services), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
975 {17, offsetof(google_protobuf_FileOptions, java_generic_services), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
976 {18, offsetof(google_protobuf_FileOptions, py_generic_services), 4, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
977 {20, offsetof(google_protobuf_FileOptions, java_generate_equals_and_hash), 5, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
978 {23, offsetof(google_protobuf_FileOptions, deprecated), 6, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
979 {27, offsetof(google_protobuf_FileOptions, java_string_check_utf8), 7, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
980 {31, offsetof(google_protobuf_FileOptions, cc_enable_arenas), 8, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
981 {36, offsetof(google_protobuf_FileOptions, objc_class_prefix), 13, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
982 {37, offsetof(google_protobuf_FileOptions, csharp_namespace), 14, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
983 {39, offsetof(google_protobuf_FileOptions, swift_prefix), 15, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
984 {40, offsetof(google_protobuf_FileOptions, php_class_prefix), 16, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
985 {41, offsetof(google_protobuf_FileOptions, php_namespace), 17, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
986 {42, offsetof(google_protobuf_FileOptions, php_generic_services), 9, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
987 {999, offsetof(google_protobuf_FileOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
988};
989
990const upb_msglayout_msginit_v1 google_protobuf_FileOptions_msginit = {
991 &google_protobuf_FileOptions_submsgs[0],
992 &google_protobuf_FileOptions__fields[0],
993 NULL,
994 NULL, /* TODO. default_msg */
995 UPB_ALIGNED_SIZEOF(google_protobuf_FileOptions), 19, 0, false, true
996};
997
998google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_env *env) {
999 google_protobuf_FileOptions *msg = upb_env_malloc(env, sizeof(*msg));
1000 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1001 return msg;
1002}
1003google_protobuf_FileOptions *google_protobuf_FileOptions_parsenew(upb_stringview buf, upb_env *env) {
1004 google_protobuf_FileOptions *msg = google_protobuf_FileOptions_new(env);
1005 if (upb_decode(buf, msg, &google_protobuf_FileOptions_msginit, env)) {
1006 return msg;
1007 } else {
1008 return NULL;
1009 }
1010}
1011char *google_protobuf_FileOptions_serialize(google_protobuf_FileOptions *msg, upb_env *env, size_t *size) {
1012 return upb_encode(msg, &google_protobuf_FileOptions_msginit, env, size);
1013}
1014upb_stringview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) {
1015 return msg->java_package;
1016}
1017void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_stringview value) {
1018 msg->java_package = value;
1019}
1020upb_stringview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) {
1021 return msg->java_outer_classname;
1022}
1023void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_stringview value) {
1024 msg->java_outer_classname = value;
1025}
1026google_protobuf_FileOptions_OptimizeMode google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) {
1027 return msg->optimize_for;
1028}
1029void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, google_protobuf_FileOptions_OptimizeMode value) {
1030 msg->optimize_for = value;
1031}
1032bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) {
1033 return msg->java_multiple_files;
1034}
1035void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) {
1036 msg->java_multiple_files = value;
1037}
1038upb_stringview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) {
1039 return msg->go_package;
1040}
1041void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_stringview value) {
1042 msg->go_package = value;
1043}
1044bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) {
1045 return msg->cc_generic_services;
1046}
1047void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) {
1048 msg->cc_generic_services = value;
1049}
1050bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) {
1051 return msg->java_generic_services;
1052}
1053void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) {
1054 msg->java_generic_services = value;
1055}
1056bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) {
1057 return msg->py_generic_services;
1058}
1059void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) {
1060 msg->py_generic_services = value;
1061}
1062bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) {
1063 return msg->java_generate_equals_and_hash;
1064}
1065void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) {
1066 msg->java_generate_equals_and_hash = value;
1067}
1068bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) {
1069 return msg->deprecated;
1070}
1071void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) {
1072 msg->deprecated = value;
1073}
1074bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) {
1075 return msg->java_string_check_utf8;
1076}
1077void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) {
1078 msg->java_string_check_utf8 = value;
1079}
1080bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) {
1081 return msg->cc_enable_arenas;
1082}
1083void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) {
1084 msg->cc_enable_arenas = value;
1085}
1086upb_stringview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) {
1087 return msg->objc_class_prefix;
1088}
1089void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_stringview value) {
1090 msg->objc_class_prefix = value;
1091}
1092upb_stringview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) {
1093 return msg->csharp_namespace;
1094}
1095void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_stringview value) {
1096 msg->csharp_namespace = value;
1097}
1098upb_stringview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) {
1099 return msg->swift_prefix;
1100}
1101void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_stringview value) {
1102 msg->swift_prefix = value;
1103}
1104upb_stringview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) {
1105 return msg->php_class_prefix;
1106}
1107void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_stringview value) {
1108 msg->php_class_prefix = value;
1109}
1110upb_stringview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) {
1111 return msg->php_namespace;
1112}
1113void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_stringview value) {
1114 msg->php_namespace = value;
1115}
1116bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) {
1117 return msg->php_generic_services;
1118}
1119void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) {
1120 msg->php_generic_services = value;
1121}
1122const upb_array* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg) {
1123 return msg->uninterpreted_option;
1124}
1125void google_protobuf_FileOptions_set_uninterpreted_option(google_protobuf_FileOptions *msg, upb_array* value) {
1126 msg->uninterpreted_option = value;
1127}
1128struct google_protobuf_MessageOptions {
1129 bool message_set_wire_format;
1130 bool no_standard_descriptor_accessor;
1131 bool deprecated;
1132 bool map_entry;
1133 upb_array* uninterpreted_option;
1134};
1135
1136static const upb_msglayout_msginit_v1 *const google_protobuf_MessageOptions_submsgs[1] = {
1137 &google_protobuf_UninterpretedOption_msginit,
1138};
1139
1140static const upb_msglayout_fieldinit_v1 google_protobuf_MessageOptions__fields[5] = {
1141 {1, offsetof(google_protobuf_MessageOptions, message_set_wire_format), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1142 {2, offsetof(google_protobuf_MessageOptions, no_standard_descriptor_accessor), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1143 {3, offsetof(google_protobuf_MessageOptions, deprecated), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1144 {7, offsetof(google_protobuf_MessageOptions, map_entry), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1145 {999, offsetof(google_protobuf_MessageOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1146};
1147
1148const upb_msglayout_msginit_v1 google_protobuf_MessageOptions_msginit = {
1149 &google_protobuf_MessageOptions_submsgs[0],
1150 &google_protobuf_MessageOptions__fields[0],
1151 NULL,
1152 NULL, /* TODO. default_msg */
1153 UPB_ALIGNED_SIZEOF(google_protobuf_MessageOptions), 5, 0, false, true
1154};
1155
1156google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_env *env) {
1157 google_protobuf_MessageOptions *msg = upb_env_malloc(env, sizeof(*msg));
1158 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1159 return msg;
1160}
1161google_protobuf_MessageOptions *google_protobuf_MessageOptions_parsenew(upb_stringview buf, upb_env *env) {
1162 google_protobuf_MessageOptions *msg = google_protobuf_MessageOptions_new(env);
1163 if (upb_decode(buf, msg, &google_protobuf_MessageOptions_msginit, env)) {
1164 return msg;
1165 } else {
1166 return NULL;
1167 }
1168}
1169char *google_protobuf_MessageOptions_serialize(google_protobuf_MessageOptions *msg, upb_env *env, size_t *size) {
1170 return upb_encode(msg, &google_protobuf_MessageOptions_msginit, env, size);
1171}
1172bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) {
1173 return msg->message_set_wire_format;
1174}
1175void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) {
1176 msg->message_set_wire_format = value;
1177}
1178bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) {
1179 return msg->no_standard_descriptor_accessor;
1180}
1181void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) {
1182 msg->no_standard_descriptor_accessor = value;
1183}
1184bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) {
1185 return msg->deprecated;
1186}
1187void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) {
1188 msg->deprecated = value;
1189}
1190bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) {
1191 return msg->map_entry;
1192}
1193void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) {
1194 msg->map_entry = value;
1195}
1196const upb_array* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg) {
1197 return msg->uninterpreted_option;
1198}
1199void google_protobuf_MessageOptions_set_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_array* value) {
1200 msg->uninterpreted_option = value;
1201}
1202struct google_protobuf_FieldOptions {
1203 google_protobuf_FieldOptions_CType ctype;
1204 google_protobuf_FieldOptions_JSType jstype;
1205 bool packed;
1206 bool deprecated;
1207 bool lazy;
1208 bool weak;
1209 upb_array* uninterpreted_option;
1210};
1211
1212static const upb_msglayout_msginit_v1 *const google_protobuf_FieldOptions_submsgs[1] = {
1213 &google_protobuf_UninterpretedOption_msginit,
1214};
1215
1216static const upb_msglayout_fieldinit_v1 google_protobuf_FieldOptions__fields[7] = {
1217 {1, offsetof(google_protobuf_FieldOptions, ctype), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
1218 {2, offsetof(google_protobuf_FieldOptions, packed), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1219 {3, offsetof(google_protobuf_FieldOptions, deprecated), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1220 {5, offsetof(google_protobuf_FieldOptions, lazy), 4, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1221 {6, offsetof(google_protobuf_FieldOptions, jstype), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
1222 {10, offsetof(google_protobuf_FieldOptions, weak), 5, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1223 {999, offsetof(google_protobuf_FieldOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1224};
1225
1226const upb_msglayout_msginit_v1 google_protobuf_FieldOptions_msginit = {
1227 &google_protobuf_FieldOptions_submsgs[0],
1228 &google_protobuf_FieldOptions__fields[0],
1229 NULL,
1230 NULL, /* TODO. default_msg */
1231 UPB_ALIGNED_SIZEOF(google_protobuf_FieldOptions), 7, 0, false, true
1232};
1233
1234google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_env *env) {
1235 google_protobuf_FieldOptions *msg = upb_env_malloc(env, sizeof(*msg));
1236 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1237 return msg;
1238}
1239google_protobuf_FieldOptions *google_protobuf_FieldOptions_parsenew(upb_stringview buf, upb_env *env) {
1240 google_protobuf_FieldOptions *msg = google_protobuf_FieldOptions_new(env);
1241 if (upb_decode(buf, msg, &google_protobuf_FieldOptions_msginit, env)) {
1242 return msg;
1243 } else {
1244 return NULL;
1245 }
1246}
1247char *google_protobuf_FieldOptions_serialize(google_protobuf_FieldOptions *msg, upb_env *env, size_t *size) {
1248 return upb_encode(msg, &google_protobuf_FieldOptions_msginit, env, size);
1249}
1250google_protobuf_FieldOptions_CType google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) {
1251 return msg->ctype;
1252}
1253void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_CType value) {
1254 msg->ctype = value;
1255}
1256bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) {
1257 return msg->packed;
1258}
1259void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) {
1260 msg->packed = value;
1261}
1262bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) {
1263 return msg->deprecated;
1264}
1265void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) {
1266 msg->deprecated = value;
1267}
1268bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) {
1269 return msg->lazy;
1270}
1271void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) {
1272 msg->lazy = value;
1273}
1274google_protobuf_FieldOptions_JSType google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) {
1275 return msg->jstype;
1276}
1277void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, google_protobuf_FieldOptions_JSType value) {
1278 msg->jstype = value;
1279}
1280bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) {
1281 return msg->weak;
1282}
1283void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) {
1284 msg->weak = value;
1285}
1286const upb_array* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg) {
1287 return msg->uninterpreted_option;
1288}
1289void google_protobuf_FieldOptions_set_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_array* value) {
1290 msg->uninterpreted_option = value;
1291}
1292struct google_protobuf_OneofOptions {
1293 upb_array* uninterpreted_option;
1294};
1295
1296static const upb_msglayout_msginit_v1 *const google_protobuf_OneofOptions_submsgs[1] = {
1297 &google_protobuf_UninterpretedOption_msginit,
1298};
1299
1300static const upb_msglayout_fieldinit_v1 google_protobuf_OneofOptions__fields[1] = {
1301 {999, offsetof(google_protobuf_OneofOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1302};
1303
1304const upb_msglayout_msginit_v1 google_protobuf_OneofOptions_msginit = {
1305 &google_protobuf_OneofOptions_submsgs[0],
1306 &google_protobuf_OneofOptions__fields[0],
1307 NULL,
1308 NULL, /* TODO. default_msg */
1309 UPB_ALIGNED_SIZEOF(google_protobuf_OneofOptions), 1, 0, false, true
1310};
1311
1312google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_env *env) {
1313 google_protobuf_OneofOptions *msg = upb_env_malloc(env, sizeof(*msg));
1314 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1315 return msg;
1316}
1317google_protobuf_OneofOptions *google_protobuf_OneofOptions_parsenew(upb_stringview buf, upb_env *env) {
1318 google_protobuf_OneofOptions *msg = google_protobuf_OneofOptions_new(env);
1319 if (upb_decode(buf, msg, &google_protobuf_OneofOptions_msginit, env)) {
1320 return msg;
1321 } else {
1322 return NULL;
1323 }
1324}
1325char *google_protobuf_OneofOptions_serialize(google_protobuf_OneofOptions *msg, upb_env *env, size_t *size) {
1326 return upb_encode(msg, &google_protobuf_OneofOptions_msginit, env, size);
1327}
1328const upb_array* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg) {
1329 return msg->uninterpreted_option;
1330}
1331void google_protobuf_OneofOptions_set_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_array* value) {
1332 msg->uninterpreted_option = value;
1333}
1334struct google_protobuf_EnumOptions {
1335 bool allow_alias;
1336 bool deprecated;
1337 upb_array* uninterpreted_option;
1338};
1339
1340static const upb_msglayout_msginit_v1 *const google_protobuf_EnumOptions_submsgs[1] = {
1341 &google_protobuf_UninterpretedOption_msginit,
1342};
1343
1344static const upb_msglayout_fieldinit_v1 google_protobuf_EnumOptions__fields[3] = {
1345 {2, offsetof(google_protobuf_EnumOptions, allow_alias), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1346 {3, offsetof(google_protobuf_EnumOptions, deprecated), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1347 {999, offsetof(google_protobuf_EnumOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1348};
1349
1350const upb_msglayout_msginit_v1 google_protobuf_EnumOptions_msginit = {
1351 &google_protobuf_EnumOptions_submsgs[0],
1352 &google_protobuf_EnumOptions__fields[0],
1353 NULL,
1354 NULL, /* TODO. default_msg */
1355 UPB_ALIGNED_SIZEOF(google_protobuf_EnumOptions), 3, 0, false, true
1356};
1357
1358google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_env *env) {
1359 google_protobuf_EnumOptions *msg = upb_env_malloc(env, sizeof(*msg));
1360 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1361 return msg;
1362}
1363google_protobuf_EnumOptions *google_protobuf_EnumOptions_parsenew(upb_stringview buf, upb_env *env) {
1364 google_protobuf_EnumOptions *msg = google_protobuf_EnumOptions_new(env);
1365 if (upb_decode(buf, msg, &google_protobuf_EnumOptions_msginit, env)) {
1366 return msg;
1367 } else {
1368 return NULL;
1369 }
1370}
1371char *google_protobuf_EnumOptions_serialize(google_protobuf_EnumOptions *msg, upb_env *env, size_t *size) {
1372 return upb_encode(msg, &google_protobuf_EnumOptions_msginit, env, size);
1373}
1374bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) {
1375 return msg->allow_alias;
1376}
1377void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) {
1378 msg->allow_alias = value;
1379}
1380bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) {
1381 return msg->deprecated;
1382}
1383void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) {
1384 msg->deprecated = value;
1385}
1386const upb_array* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg) {
1387 return msg->uninterpreted_option;
1388}
1389void google_protobuf_EnumOptions_set_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_array* value) {
1390 msg->uninterpreted_option = value;
1391}
1392struct google_protobuf_EnumValueOptions {
1393 bool deprecated;
1394 upb_array* uninterpreted_option;
1395};
1396
1397static const upb_msglayout_msginit_v1 *const google_protobuf_EnumValueOptions_submsgs[1] = {
1398 &google_protobuf_UninterpretedOption_msginit,
1399};
1400
1401static const upb_msglayout_fieldinit_v1 google_protobuf_EnumValueOptions__fields[2] = {
1402 {1, offsetof(google_protobuf_EnumValueOptions, deprecated), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1403 {999, offsetof(google_protobuf_EnumValueOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1404};
1405
1406const upb_msglayout_msginit_v1 google_protobuf_EnumValueOptions_msginit = {
1407 &google_protobuf_EnumValueOptions_submsgs[0],
1408 &google_protobuf_EnumValueOptions__fields[0],
1409 NULL,
1410 NULL, /* TODO. default_msg */
1411 UPB_ALIGNED_SIZEOF(google_protobuf_EnumValueOptions), 2, 0, false, true
1412};
1413
1414google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_env *env) {
1415 google_protobuf_EnumValueOptions *msg = upb_env_malloc(env, sizeof(*msg));
1416 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1417 return msg;
1418}
1419google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parsenew(upb_stringview buf, upb_env *env) {
1420 google_protobuf_EnumValueOptions *msg = google_protobuf_EnumValueOptions_new(env);
1421 if (upb_decode(buf, msg, &google_protobuf_EnumValueOptions_msginit, env)) {
1422 return msg;
1423 } else {
1424 return NULL;
1425 }
1426}
1427char *google_protobuf_EnumValueOptions_serialize(google_protobuf_EnumValueOptions *msg, upb_env *env, size_t *size) {
1428 return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, env, size);
1429}
1430bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) {
1431 return msg->deprecated;
1432}
1433void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) {
1434 msg->deprecated = value;
1435}
1436const upb_array* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) {
1437 return msg->uninterpreted_option;
1438}
1439void google_protobuf_EnumValueOptions_set_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_array* value) {
1440 msg->uninterpreted_option = value;
1441}
1442struct google_protobuf_ServiceOptions {
1443 bool deprecated;
1444 upb_array* uninterpreted_option;
1445};
1446
1447static const upb_msglayout_msginit_v1 *const google_protobuf_ServiceOptions_submsgs[1] = {
1448 &google_protobuf_UninterpretedOption_msginit,
1449};
1450
1451static const upb_msglayout_fieldinit_v1 google_protobuf_ServiceOptions__fields[2] = {
1452 {33, offsetof(google_protobuf_ServiceOptions, deprecated), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1453 {999, offsetof(google_protobuf_ServiceOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1454};
1455
1456const upb_msglayout_msginit_v1 google_protobuf_ServiceOptions_msginit = {
1457 &google_protobuf_ServiceOptions_submsgs[0],
1458 &google_protobuf_ServiceOptions__fields[0],
1459 NULL,
1460 NULL, /* TODO. default_msg */
1461 UPB_ALIGNED_SIZEOF(google_protobuf_ServiceOptions), 2, 0, false, true
1462};
1463
1464google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_env *env) {
1465 google_protobuf_ServiceOptions *msg = upb_env_malloc(env, sizeof(*msg));
1466 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1467 return msg;
1468}
1469google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parsenew(upb_stringview buf, upb_env *env) {
1470 google_protobuf_ServiceOptions *msg = google_protobuf_ServiceOptions_new(env);
1471 if (upb_decode(buf, msg, &google_protobuf_ServiceOptions_msginit, env)) {
1472 return msg;
1473 } else {
1474 return NULL;
1475 }
1476}
1477char *google_protobuf_ServiceOptions_serialize(google_protobuf_ServiceOptions *msg, upb_env *env, size_t *size) {
1478 return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, env, size);
1479}
1480bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) {
1481 return msg->deprecated;
1482}
1483void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) {
1484 msg->deprecated = value;
1485}
1486const upb_array* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg) {
1487 return msg->uninterpreted_option;
1488}
1489void google_protobuf_ServiceOptions_set_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_array* value) {
1490 msg->uninterpreted_option = value;
1491}
1492struct google_protobuf_MethodOptions {
1493 google_protobuf_MethodOptions_IdempotencyLevel idempotency_level;
1494 bool deprecated;
1495 upb_array* uninterpreted_option;
1496};
1497
1498static const upb_msglayout_msginit_v1 *const google_protobuf_MethodOptions_submsgs[1] = {
1499 &google_protobuf_UninterpretedOption_msginit,
1500};
1501
1502static const upb_msglayout_fieldinit_v1 google_protobuf_MethodOptions__fields[3] = {
1503 {33, offsetof(google_protobuf_MethodOptions, deprecated), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 1},
1504 {34, offsetof(google_protobuf_MethodOptions, idempotency_level), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 14, 1},
1505 {999, offsetof(google_protobuf_MethodOptions, uninterpreted_option), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1506};
1507
1508const upb_msglayout_msginit_v1 google_protobuf_MethodOptions_msginit = {
1509 &google_protobuf_MethodOptions_submsgs[0],
1510 &google_protobuf_MethodOptions__fields[0],
1511 NULL,
1512 NULL, /* TODO. default_msg */
1513 UPB_ALIGNED_SIZEOF(google_protobuf_MethodOptions), 3, 0, false, true
1514};
1515
1516google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_env *env) {
1517 google_protobuf_MethodOptions *msg = upb_env_malloc(env, sizeof(*msg));
1518 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1519 return msg;
1520}
1521google_protobuf_MethodOptions *google_protobuf_MethodOptions_parsenew(upb_stringview buf, upb_env *env) {
1522 google_protobuf_MethodOptions *msg = google_protobuf_MethodOptions_new(env);
1523 if (upb_decode(buf, msg, &google_protobuf_MethodOptions_msginit, env)) {
1524 return msg;
1525 } else {
1526 return NULL;
1527 }
1528}
1529char *google_protobuf_MethodOptions_serialize(google_protobuf_MethodOptions *msg, upb_env *env, size_t *size) {
1530 return upb_encode(msg, &google_protobuf_MethodOptions_msginit, env, size);
1531}
1532bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) {
1533 return msg->deprecated;
1534}
1535void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) {
1536 msg->deprecated = value;
1537}
1538google_protobuf_MethodOptions_IdempotencyLevel google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) {
1539 return msg->idempotency_level;
1540}
1541void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, google_protobuf_MethodOptions_IdempotencyLevel value) {
1542 msg->idempotency_level = value;
1543}
1544const upb_array* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg) {
1545 return msg->uninterpreted_option;
1546}
1547void google_protobuf_MethodOptions_set_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_array* value) {
1548 msg->uninterpreted_option = value;
1549}
1550struct google_protobuf_UninterpretedOption {
1551 uint64_t positive_int_value;
1552 int64_t negative_int_value;
1553 double double_value;
1554 upb_stringview identifier_value;
1555 upb_stringview string_value;
1556 upb_stringview aggregate_value;
1557 upb_array* name;
1558};
1559
1560static const upb_msglayout_msginit_v1 *const google_protobuf_UninterpretedOption_submsgs[1] = {
1561 &google_protobuf_UninterpretedOption_NamePart_msginit,
1562};
1563
1564static const upb_msglayout_fieldinit_v1 google_protobuf_UninterpretedOption__fields[7] = {
1565 {2, offsetof(google_protobuf_UninterpretedOption, name), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1566 {3, offsetof(google_protobuf_UninterpretedOption, identifier_value), 3, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
1567 {4, offsetof(google_protobuf_UninterpretedOption, positive_int_value), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 4, 1},
1568 {5, offsetof(google_protobuf_UninterpretedOption, negative_int_value), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 3, 1},
1569 {6, offsetof(google_protobuf_UninterpretedOption, double_value), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 1, 1},
1570 {7, offsetof(google_protobuf_UninterpretedOption, string_value), 4, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 12, 1},
1571 {8, offsetof(google_protobuf_UninterpretedOption, aggregate_value), 5, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
1572};
1573
1574const upb_msglayout_msginit_v1 google_protobuf_UninterpretedOption_msginit = {
1575 &google_protobuf_UninterpretedOption_submsgs[0],
1576 &google_protobuf_UninterpretedOption__fields[0],
1577 NULL,
1578 NULL, /* TODO. default_msg */
1579 UPB_ALIGNED_SIZEOF(google_protobuf_UninterpretedOption), 7, 0, false, true
1580};
1581
1582google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_env *env) {
1583 google_protobuf_UninterpretedOption *msg = upb_env_malloc(env, sizeof(*msg));
1584 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1585 return msg;
1586}
1587google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parsenew(upb_stringview buf, upb_env *env) {
1588 google_protobuf_UninterpretedOption *msg = google_protobuf_UninterpretedOption_new(env);
1589 if (upb_decode(buf, msg, &google_protobuf_UninterpretedOption_msginit, env)) {
1590 return msg;
1591 } else {
1592 return NULL;
1593 }
1594}
1595char *google_protobuf_UninterpretedOption_serialize(google_protobuf_UninterpretedOption *msg, upb_env *env, size_t *size) {
1596 return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, env, size);
1597}
1598const upb_array* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg) {
1599 return msg->name;
1600}
1601void google_protobuf_UninterpretedOption_set_name(google_protobuf_UninterpretedOption *msg, upb_array* value) {
1602 msg->name = value;
1603}
1604upb_stringview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) {
1605 return msg->identifier_value;
1606}
1607void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) {
1608 msg->identifier_value = value;
1609}
1610uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) {
1611 return msg->positive_int_value;
1612}
1613void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) {
1614 msg->positive_int_value = value;
1615}
1616int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) {
1617 return msg->negative_int_value;
1618}
1619void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) {
1620 msg->negative_int_value = value;
1621}
1622double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) {
1623 return msg->double_value;
1624}
1625void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) {
1626 msg->double_value = value;
1627}
1628upb_stringview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) {
1629 return msg->string_value;
1630}
1631void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) {
1632 msg->string_value = value;
1633}
1634upb_stringview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) {
1635 return msg->aggregate_value;
1636}
1637void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_stringview value) {
1638 msg->aggregate_value = value;
1639}
1640struct google_protobuf_UninterpretedOption_NamePart {
1641 bool is_extension;
1642 upb_stringview name_part;
1643};
1644
1645static const upb_msglayout_fieldinit_v1 google_protobuf_UninterpretedOption_NamePart__fields[2] = {
1646 {1, offsetof(google_protobuf_UninterpretedOption_NamePart, name_part), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 2},
1647 {2, offsetof(google_protobuf_UninterpretedOption_NamePart, is_extension), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 8, 2},
1648};
1649
1650const upb_msglayout_msginit_v1 google_protobuf_UninterpretedOption_NamePart_msginit = {
1651 NULL,
1652 &google_protobuf_UninterpretedOption_NamePart__fields[0],
1653 NULL,
1654 NULL, /* TODO. default_msg */
1655 UPB_ALIGNED_SIZEOF(google_protobuf_UninterpretedOption_NamePart), 2, 0, false, true
1656};
1657
1658google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_env *env) {
1659 google_protobuf_UninterpretedOption_NamePart *msg = upb_env_malloc(env, sizeof(*msg));
1660 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1661 return msg;
1662}
1663google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parsenew(upb_stringview buf, upb_env *env) {
1664 google_protobuf_UninterpretedOption_NamePart *msg = google_protobuf_UninterpretedOption_NamePart_new(env);
1665 if (upb_decode(buf, msg, &google_protobuf_UninterpretedOption_NamePart_msginit, env)) {
1666 return msg;
1667 } else {
1668 return NULL;
1669 }
1670}
1671char *google_protobuf_UninterpretedOption_NamePart_serialize(google_protobuf_UninterpretedOption_NamePart *msg, upb_env *env, size_t *size) {
1672 return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, env, size);
1673}
1674upb_stringview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) {
1675 return msg->name_part;
1676}
1677void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_stringview value) {
1678 msg->name_part = value;
1679}
1680bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) {
1681 return msg->is_extension;
1682}
1683void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) {
1684 msg->is_extension = value;
1685}
1686struct google_protobuf_SourceCodeInfo {
1687 upb_array* location;
1688};
1689
1690static const upb_msglayout_msginit_v1 *const google_protobuf_SourceCodeInfo_submsgs[1] = {
1691 &google_protobuf_SourceCodeInfo_Location_msginit,
1692};
1693
1694static const upb_msglayout_fieldinit_v1 google_protobuf_SourceCodeInfo__fields[1] = {
1695 {1, offsetof(google_protobuf_SourceCodeInfo, location), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1696};
1697
1698const upb_msglayout_msginit_v1 google_protobuf_SourceCodeInfo_msginit = {
1699 &google_protobuf_SourceCodeInfo_submsgs[0],
1700 &google_protobuf_SourceCodeInfo__fields[0],
1701 NULL,
1702 NULL, /* TODO. default_msg */
1703 UPB_ALIGNED_SIZEOF(google_protobuf_SourceCodeInfo), 1, 0, false, true
1704};
1705
1706google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_env *env) {
1707 google_protobuf_SourceCodeInfo *msg = upb_env_malloc(env, sizeof(*msg));
1708 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1709 return msg;
1710}
1711google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parsenew(upb_stringview buf, upb_env *env) {
1712 google_protobuf_SourceCodeInfo *msg = google_protobuf_SourceCodeInfo_new(env);
1713 if (upb_decode(buf, msg, &google_protobuf_SourceCodeInfo_msginit, env)) {
1714 return msg;
1715 } else {
1716 return NULL;
1717 }
1718}
1719char *google_protobuf_SourceCodeInfo_serialize(google_protobuf_SourceCodeInfo *msg, upb_env *env, size_t *size) {
1720 return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, env, size);
1721}
1722const upb_array* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg) {
1723 return msg->location;
1724}
1725void google_protobuf_SourceCodeInfo_set_location(google_protobuf_SourceCodeInfo *msg, upb_array* value) {
1726 msg->location = value;
1727}
1728struct google_protobuf_SourceCodeInfo_Location {
1729 upb_stringview leading_comments;
1730 upb_stringview trailing_comments;
1731 upb_array* path;
1732 upb_array* span;
1733 upb_array* leading_detached_comments;
1734};
1735
1736static const upb_msglayout_fieldinit_v1 google_protobuf_SourceCodeInfo_Location__fields[5] = {
1737 {1, offsetof(google_protobuf_SourceCodeInfo_Location, path), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 3},
1738 {2, offsetof(google_protobuf_SourceCodeInfo_Location, span), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 3},
1739 {3, offsetof(google_protobuf_SourceCodeInfo_Location, leading_comments), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
1740 {4, offsetof(google_protobuf_SourceCodeInfo_Location, trailing_comments), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
1741 {6, offsetof(google_protobuf_SourceCodeInfo_Location, leading_detached_comments), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 3},
1742};
1743
1744const upb_msglayout_msginit_v1 google_protobuf_SourceCodeInfo_Location_msginit = {
1745 NULL,
1746 &google_protobuf_SourceCodeInfo_Location__fields[0],
1747 NULL,
1748 NULL, /* TODO. default_msg */
1749 UPB_ALIGNED_SIZEOF(google_protobuf_SourceCodeInfo_Location), 5, 0, false, true
1750};
1751
1752google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_env *env) {
1753 google_protobuf_SourceCodeInfo_Location *msg = upb_env_malloc(env, sizeof(*msg));
1754 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1755 return msg;
1756}
1757google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parsenew(upb_stringview buf, upb_env *env) {
1758 google_protobuf_SourceCodeInfo_Location *msg = google_protobuf_SourceCodeInfo_Location_new(env);
1759 if (upb_decode(buf, msg, &google_protobuf_SourceCodeInfo_Location_msginit, env)) {
1760 return msg;
1761 } else {
1762 return NULL;
1763 }
1764}
1765char *google_protobuf_SourceCodeInfo_Location_serialize(google_protobuf_SourceCodeInfo_Location *msg, upb_env *env, size_t *size) {
1766 return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, env, size);
1767}
1768const upb_array* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg) {
1769 return msg->path;
1770}
1771void google_protobuf_SourceCodeInfo_Location_set_path(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) {
1772 msg->path = value;
1773}
1774const upb_array* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg) {
1775 return msg->span;
1776}
1777void google_protobuf_SourceCodeInfo_Location_set_span(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) {
1778 msg->span = value;
1779}
1780upb_stringview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) {
1781 return msg->leading_comments;
1782}
1783void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_stringview value) {
1784 msg->leading_comments = value;
1785}
1786upb_stringview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) {
1787 return msg->trailing_comments;
1788}
1789void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_stringview value) {
1790 msg->trailing_comments = value;
1791}
1792const upb_array* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg) {
1793 return msg->leading_detached_comments;
1794}
1795void google_protobuf_SourceCodeInfo_Location_set_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_array* value) {
1796 msg->leading_detached_comments = value;
1797}
1798struct google_protobuf_GeneratedCodeInfo {
1799 upb_array* annotation;
1800};
1801
1802static const upb_msglayout_msginit_v1 *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
1803 &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
1804};
1805
1806static const upb_msglayout_fieldinit_v1 google_protobuf_GeneratedCodeInfo__fields[1] = {
1807 {1, offsetof(google_protobuf_GeneratedCodeInfo, annotation), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, 0, 11, 3},
1808};
1809
1810const upb_msglayout_msginit_v1 google_protobuf_GeneratedCodeInfo_msginit = {
1811 &google_protobuf_GeneratedCodeInfo_submsgs[0],
1812 &google_protobuf_GeneratedCodeInfo__fields[0],
1813 NULL,
1814 NULL, /* TODO. default_msg */
1815 UPB_ALIGNED_SIZEOF(google_protobuf_GeneratedCodeInfo), 1, 0, false, true
1816};
1817
1818google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_env *env) {
1819 google_protobuf_GeneratedCodeInfo *msg = upb_env_malloc(env, sizeof(*msg));
1820 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1821 return msg;
1822}
1823google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parsenew(upb_stringview buf, upb_env *env) {
1824 google_protobuf_GeneratedCodeInfo *msg = google_protobuf_GeneratedCodeInfo_new(env);
1825 if (upb_decode(buf, msg, &google_protobuf_GeneratedCodeInfo_msginit, env)) {
1826 return msg;
1827 } else {
1828 return NULL;
1829 }
1830}
1831char *google_protobuf_GeneratedCodeInfo_serialize(google_protobuf_GeneratedCodeInfo *msg, upb_env *env, size_t *size) {
1832 return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, env, size);
1833}
1834const upb_array* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg) {
1835 return msg->annotation;
1836}
1837void google_protobuf_GeneratedCodeInfo_set_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_array* value) {
1838 msg->annotation = value;
1839}
1840struct google_protobuf_GeneratedCodeInfo_Annotation {
1841 int32_t begin;
1842 int32_t end;
1843 upb_stringview source_file;
1844 upb_array* path;
1845};
1846
1847static const upb_msglayout_fieldinit_v1 google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
1848 {1, offsetof(google_protobuf_GeneratedCodeInfo_Annotation, path), UPB_NO_HASBIT, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 3},
1849 {2, offsetof(google_protobuf_GeneratedCodeInfo_Annotation, source_file), 2, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 9, 1},
1850 {3, offsetof(google_protobuf_GeneratedCodeInfo_Annotation, begin), 0, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
1851 {4, offsetof(google_protobuf_GeneratedCodeInfo_Annotation, end), 1, UPB_NOT_IN_ONEOF, UPB_NO_SUBMSG, 5, 1},
1852};
1853
1854const upb_msglayout_msginit_v1 google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
1855 NULL,
1856 &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
1857 NULL,
1858 NULL, /* TODO. default_msg */
1859 UPB_ALIGNED_SIZEOF(google_protobuf_GeneratedCodeInfo_Annotation), 4, 0, false, true
1860};
1861
1862google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_env *env) {
1863 google_protobuf_GeneratedCodeInfo_Annotation *msg = upb_env_malloc(env, sizeof(*msg));
1864 memset(msg, 0, sizeof(*msg)); /* TODO: defaults */
1865 return msg;
1866}
1867google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parsenew(upb_stringview buf, upb_env *env) {
1868 google_protobuf_GeneratedCodeInfo_Annotation *msg = google_protobuf_GeneratedCodeInfo_Annotation_new(env);
1869 if (upb_decode(buf, msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, env)) {
1870 return msg;
1871 } else {
1872 return NULL;
1873 }
1874}
1875char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_env *env, size_t *size) {
1876 return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, env, size);
1877}
1878const upb_array* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg) {
1879 return msg->path;
1880}
1881void google_protobuf_GeneratedCodeInfo_Annotation_set_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_array* value) {
1882 msg->path = value;
1883}
1884upb_stringview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) {
1885 return msg->source_file;
1886}
1887void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_stringview value) {
1888 msg->source_file = value;
1889}
1890int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) {
1891 return msg->begin;
1892}
1893void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
1894 msg->begin = value;
1895}
1896int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) {
1897 return msg->end;
1898}
1899void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
1900 msg->end = value;
1901}
1902
1903
1904/* Maps descriptor type -> upb field type. */
1905const uint8_t upb_desctype_to_fieldtype[] = {
1906 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
1907 UPB_TYPE_DOUBLE, /* DOUBLE */
1908 UPB_TYPE_FLOAT, /* FLOAT */
1909 UPB_TYPE_INT64, /* INT64 */
1910 UPB_TYPE_UINT64, /* UINT64 */
1911 UPB_TYPE_INT32, /* INT32 */
1912 UPB_TYPE_UINT64, /* FIXED64 */
1913 UPB_TYPE_UINT32, /* FIXED32 */
1914 UPB_TYPE_BOOL, /* BOOL */
1915 UPB_TYPE_STRING, /* STRING */
1916 UPB_TYPE_MESSAGE, /* GROUP */
1917 UPB_TYPE_MESSAGE, /* MESSAGE */
1918 UPB_TYPE_BYTES, /* BYTES */
1919 UPB_TYPE_UINT32, /* UINT32 */
1920 UPB_TYPE_ENUM, /* ENUM */
1921 UPB_TYPE_INT32, /* SFIXED32 */
1922 UPB_TYPE_INT64, /* SFIXED64 */
1923 UPB_TYPE_INT32, /* SINT32 */
1924 UPB_TYPE_INT64, /* SINT64 */
1925};
1926
1927/* Data pertaining to the parse. */
1928typedef struct {
1929 upb_env *env;
1930 /* Current decoding pointer. Points to the beginning of a field until we
1931 * have finished decoding the whole field. */
1932 const char *ptr;
1933} upb_decstate;
1934
1935/* Data pertaining to a single message frame. */
1936typedef struct {
1937 const char *limit;
1938 int32_t group_number; /* 0 if we are not parsing a group. */
1939
1940 /* These members are unset for an unknown group frame. */
1941 char *msg;
1942 const upb_msglayout_msginit_v1 *m;
1943} upb_decframe;
1944
1945#define CHK(x) if (!(x)) { return false; }
1946
1947static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
1948 const char *limit);
1949static bool upb_decode_message(upb_decstate *d, const char *limit,
1950 int group_number, char *msg,
1951 const upb_msglayout_msginit_v1 *l);
1952
1953static bool upb_decode_varint(const char **ptr, const char *limit,
1954 uint64_t *val) {
1955 uint8_t byte;
1956 int bitpos = 0;
1957 const char *p = *ptr;
1958 *val = 0;
1959
1960 do {
1961 CHK(bitpos < 70 && p < limit);
1962 byte = *p;
1963 *val |= (uint64_t)(byte & 0x7F) << bitpos;
1964 p++;
1965 bitpos += 7;
1966 } while (byte & 0x80);
1967
1968 *ptr = p;
1969 return true;
1970}
1971
1972static bool upb_decode_varint32(const char **ptr, const char *limit,
1973 uint32_t *val) {
1974 uint64_t u64;
1975 CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
1976 *val = u64;
1977 return true;
1978}
1979
1980static bool upb_decode_64bit(const char **ptr, const char *limit,
1981 uint64_t *val) {
1982 CHK(limit - *ptr >= 8);
1983 memcpy(val, *ptr, 8);
1984 *ptr += 8;
1985 return true;
1986}
1987
1988static bool upb_decode_32bit(const char **ptr, const char *limit,
1989 uint32_t *val) {
1990 CHK(limit - *ptr >= 4);
1991 memcpy(val, *ptr, 4);
1992 *ptr += 4;
1993 return true;
1994}
1995
1996static bool upb_decode_tag(const char **ptr, const char *limit,
1997 int *field_number, int *wire_type) {
1998 uint32_t tag = 0;
1999 CHK(upb_decode_varint32(ptr, limit, &tag));
2000 *field_number = tag >> 3;
2001 *wire_type = tag & 7;
2002 return true;
2003}
2004
2005static int32_t upb_zzdecode_32(uint32_t n) {
2006 return (n >> 1) ^ -(int32_t)(n & 1);
2007}
2008
2009static int64_t upb_zzdecode_64(uint64_t n) {
2010 return (n >> 1) ^ -(int64_t)(n & 1);
2011}
2012
2013static bool upb_decode_string(const char **ptr, const char *limit,
2014 upb_stringview *val) {
2015 uint32_t len;
2016
2017 CHK(upb_decode_varint32(ptr, limit, &len) &&
2018 len < INT32_MAX &&
2019 limit - *ptr >= (int32_t)len);
2020
2021 *val = upb_stringview_make(*ptr, len);
2022 *ptr += len;
2023 return true;
2024}
2025
2026static void upb_set32(void *msg, size_t ofs, uint32_t val) {
2027 memcpy((char*)msg + ofs, &val, sizeof(val));
2028}
2029
2030static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
2031 const char *start) {
2032 UPB_UNUSED(d);
2033 UPB_UNUSED(frame);
2034 UPB_UNUSED(start);
2035 return true;
2036}
2037
2038static bool upb_skip_unknownfielddata(upb_decstate *d, upb_decframe *frame,
2039 int field_number, int wire_type) {
2040 switch (wire_type) {
2041 case UPB_WIRE_TYPE_VARINT: {
2042 uint64_t val;
2043 return upb_decode_varint(&d->ptr, frame->limit, &val);
2044 }
2045 case UPB_WIRE_TYPE_32BIT: {
2046 uint32_t val;
2047 return upb_decode_32bit(&d->ptr, frame->limit, &val);
2048 }
2049 case UPB_WIRE_TYPE_64BIT: {
2050 uint64_t val;
2051 return upb_decode_64bit(&d->ptr, frame->limit, &val);
2052 }
2053 case UPB_WIRE_TYPE_DELIMITED: {
2054 upb_stringview val;
2055 return upb_decode_string(&d->ptr, frame->limit, &val);
2056 }
2057 case UPB_WIRE_TYPE_START_GROUP:
2058 return upb_skip_unknowngroup(d, field_number, frame->limit);
2059 case UPB_WIRE_TYPE_END_GROUP:
2060 CHK(field_number == frame->group_number);
2061 frame->limit = d->ptr;
2062 return true;
2063 }
2064 return false;
2065}
2066
2067static bool upb_array_grow(upb_array *arr, size_t elements) {
2068 size_t needed = arr->len + elements;
2069 size_t new_size = UPB_MAX(arr->size, 8);
2070 size_t new_bytes;
2071 size_t old_bytes;
2072 void *new_data;
2073
2074 while (new_size < needed) {
2075 new_size *= 2;
2076 }
2077
2078 old_bytes = arr->len * arr->element_size;
2079 new_bytes = new_size * arr->element_size;
2080 new_data = upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
2081 CHK(new_data);
2082
2083 arr->data = new_data;
2084 arr->size = new_size;
2085 return true;
2086}
2087
2088static void *upb_array_reserve(upb_array *arr, size_t elements) {
2089 if (arr->size - arr->len < elements) {
2090 CHK(upb_array_grow(arr, elements));
2091 }
2092 return (char*)arr->data + (arr->len * arr->element_size);
2093}
2094
2095static void *upb_array_add(upb_array *arr, size_t elements) {
2096 void *ret = upb_array_reserve(arr, elements);
2097 arr->len += elements;
2098 return ret;
2099}
2100
2101static upb_array *upb_getarr(upb_decframe *frame,
2102 const upb_msglayout_fieldinit_v1 *field) {
2103 UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
2104 return *(upb_array**)&frame->msg[field->offset];
2105}
2106
2107static upb_array *upb_getorcreatearr(upb_decstate *d,
2108 upb_decframe *frame,
2109 const upb_msglayout_fieldinit_v1 *field) {
2110 upb_array *arr = upb_getarr(frame, field);
2111
2112 if (!arr) {
2113 arr = upb_env_malloc(d->env, sizeof(*arr));
2114 if (!arr) {
2115 return NULL;
2116 }
2117 upb_array_init(arr, upb_desctype_to_fieldtype[field->descriptortype],
2118 upb_arena_alloc(upb_env_arena(d->env)));
2119 *(upb_array**)&frame->msg[field->offset] = arr;
2120 }
2121
2122 return arr;
2123}
2124
2125static void upb_sethasbit(upb_decframe *frame,
2126 const upb_msglayout_fieldinit_v1 *field) {
2127 UPB_ASSERT(field->hasbit != UPB_NO_HASBIT);
2128 frame->msg[field->hasbit / 8] |= (1 << (field->hasbit % 8));
2129}
2130
2131static void upb_setoneofcase(upb_decframe *frame,
2132 const upb_msglayout_fieldinit_v1 *field) {
2133 UPB_ASSERT(field->oneof_index != UPB_NOT_IN_ONEOF);
2134 upb_set32(frame->msg, frame->m->oneofs[field->oneof_index].case_offset,
2135 field->number);
2136}
2137
2138static char *upb_decode_prepareslot(upb_decstate *d,
2139 upb_decframe *frame,
2140 const upb_msglayout_fieldinit_v1 *field) {
2141 char *field_mem = frame->msg + field->offset;
2142 upb_array *arr;
2143
2144 if (field->label == UPB_LABEL_REPEATED) {
2145 arr = upb_getorcreatearr(d, frame, field);
2146 field_mem = upb_array_reserve(arr, 1);
2147 }
2148
2149 return field_mem;
2150}
2151
2152static void upb_decode_setpresent(upb_decframe *frame,
2153 const upb_msglayout_fieldinit_v1 *field) {
2154 if (field->label == UPB_LABEL_REPEATED) {
2155 upb_array *arr = upb_getarr(frame, field);
2156 UPB_ASSERT(arr->len < arr->size);
2157 arr->len++;
2158 } else if (field->oneof_index != UPB_NOT_IN_ONEOF) {
2159 upb_setoneofcase(frame, field);
2160 } else if (field->hasbit != UPB_NO_HASBIT) {
2161 upb_sethasbit(frame, field);
2162 }
2163}
2164
2165static bool upb_decode_submsg(upb_decstate *d,
2166 upb_decframe *frame,
2167 const char *limit,
2168 const upb_msglayout_fieldinit_v1 *field,
2169 int group_number) {
2170 char *submsg_slot = upb_decode_prepareslot(d, frame, field);
2171 char *submsg = *(void**)submsg_slot;
2172 const upb_msglayout_msginit_v1 *subm;
2173
2174 UPB_ASSERT(field->submsg_index != UPB_NO_SUBMSG);
2175 subm = frame->m->submsgs[field->submsg_index];
2176 UPB_ASSERT(subm);
2177
2178 if (!submsg) {
2179 submsg = upb_env_malloc(d->env, upb_msg_sizeof((upb_msglayout *)subm));
2180 CHK(submsg);
2181 submsg = upb_msg_init(
2182 submsg, (upb_msglayout*)subm, upb_arena_alloc(upb_env_arena(d->env)));
2183 *(void**)submsg_slot = submsg;
2184 }
2185
2186 upb_decode_message(d, limit, group_number, submsg, subm);
2187
2188 return true;
2189}
2190
2191static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
2192 const char *field_start,
2193 const upb_msglayout_fieldinit_v1 *field) {
2194 uint64_t val;
2195 void *field_mem;
2196
2197 field_mem = upb_decode_prepareslot(d, frame, field);
2198 CHK(field_mem);
2199 CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
2200
2201 switch ((upb_descriptortype_t)field->descriptortype) {
2202 case UPB_DESCRIPTOR_TYPE_INT64:
2203 case UPB_DESCRIPTOR_TYPE_UINT64:
2204 memcpy(field_mem, &val, sizeof(val));
2205 break;
2206 case UPB_DESCRIPTOR_TYPE_INT32:
2207 case UPB_DESCRIPTOR_TYPE_UINT32:
2208 case UPB_DESCRIPTOR_TYPE_ENUM: {
2209 uint32_t val32 = val;
2210 memcpy(field_mem, &val32, sizeof(val32));
2211 break;
2212 }
2213 case UPB_DESCRIPTOR_TYPE_BOOL: {
2214 bool valbool = val != 0;
2215 memcpy(field_mem, &valbool, sizeof(valbool));
2216 break;
2217 }
2218 case UPB_DESCRIPTOR_TYPE_SINT32: {
2219 int32_t decoded = upb_zzdecode_32(val);
2220 memcpy(field_mem, &decoded, sizeof(decoded));
2221 break;
2222 }
2223 case UPB_DESCRIPTOR_TYPE_SINT64: {
2224 int64_t decoded = upb_zzdecode_64(val);
2225 memcpy(field_mem, &decoded, sizeof(decoded));
2226 break;
2227 }
2228 default:
2229 return upb_append_unknown(d, frame, field_start);
2230 }
2231
2232 upb_decode_setpresent(frame, field);
2233 return true;
2234}
2235
2236static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
2237 const char *field_start,
2238 const upb_msglayout_fieldinit_v1 *field) {
2239 void *field_mem;
2240 uint64_t val;
2241
2242 field_mem = upb_decode_prepareslot(d, frame, field);
2243 CHK(field_mem);
2244 CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
2245
2246 switch ((upb_descriptortype_t)field->descriptortype) {
2247 case UPB_DESCRIPTOR_TYPE_DOUBLE:
2248 case UPB_DESCRIPTOR_TYPE_FIXED64:
2249 case UPB_DESCRIPTOR_TYPE_SFIXED64:
2250 memcpy(field_mem, &val, sizeof(val));
2251 break;
2252 default:
2253 return upb_append_unknown(d, frame, field_start);
2254 }
2255
2256 upb_decode_setpresent(frame, field);
2257 return true;
2258}
2259
2260static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
2261 const char *field_start,
2262 const upb_msglayout_fieldinit_v1 *field) {
2263 void *field_mem;
2264 uint32_t val;
2265
2266 field_mem = upb_decode_prepareslot(d, frame, field);
2267 CHK(field_mem);
2268 CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
2269
2270 switch ((upb_descriptortype_t)field->descriptortype) {
2271 case UPB_DESCRIPTOR_TYPE_FLOAT:
2272 case UPB_DESCRIPTOR_TYPE_FIXED32:
2273 case UPB_DESCRIPTOR_TYPE_SFIXED32:
2274 memcpy(field_mem, &val, sizeof(val));
2275 break;
2276 default:
2277 return upb_append_unknown(d, frame, field_start);
2278 }
2279
2280 upb_decode_setpresent(frame, field);
2281 return true;
2282}
2283
2284static bool upb_decode_fixedpacked(upb_array *arr, upb_stringview data,
2285 int elem_size) {
2286 int elements = data.size / elem_size;
2287 void *field_mem;
2288
2289 CHK((size_t)(elements * elem_size) == data.size);
2290 field_mem = upb_array_add(arr, elements);
2291 CHK(field_mem);
2292 memcpy(field_mem, data.data, data.size);
2293 return true;
2294}
2295
2296static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
2297 const char *field_start,
2298 const upb_msglayout_fieldinit_v1 *field,
2299 upb_stringview val) {
2300 upb_array *arr = upb_getorcreatearr(d, frame, field);
2301
2302#define VARINT_CASE(ctype, decode) { \
2303 const char *ptr = val.data; \
2304 const char *limit = ptr + val.size; \
2305 while (ptr < limit) { \
2306 uint64_t val; \
2307 void *field_mem; \
2308 ctype decoded; \
2309 CHK(upb_decode_varint(&ptr, limit, &val)); \
2310 decoded = (decode)(val); \
2311 field_mem = upb_array_add(arr, 1); \
2312 CHK(field_mem); \
2313 memcpy(field_mem, &decoded, sizeof(ctype)); \
2314 } \
2315 return true; \
2316}
2317
2318 switch ((upb_descriptortype_t)field->descriptortype) {
2319 case UPB_DESCRIPTOR_TYPE_STRING:
2320 case UPB_DESCRIPTOR_TYPE_BYTES: {
2321 void *field_mem = upb_array_add(arr, 1);
2322 CHK(field_mem);
2323 memcpy(field_mem, &val, sizeof(val));
2324 return true;
2325 }
2326 case UPB_DESCRIPTOR_TYPE_FLOAT:
2327 case UPB_DESCRIPTOR_TYPE_FIXED32:
2328 case UPB_DESCRIPTOR_TYPE_SFIXED32:
2329 return upb_decode_fixedpacked(arr, val, sizeof(int32_t));
2330 case UPB_DESCRIPTOR_TYPE_DOUBLE:
2331 case UPB_DESCRIPTOR_TYPE_FIXED64:
2332 case UPB_DESCRIPTOR_TYPE_SFIXED64:
2333 return upb_decode_fixedpacked(arr, val, sizeof(int64_t));
2334 case UPB_DESCRIPTOR_TYPE_INT32:
2335 case UPB_DESCRIPTOR_TYPE_UINT32:
2336 case UPB_DESCRIPTOR_TYPE_ENUM:
2337 /* TODO: proto2 enum field that isn't in the enum. */
2338 VARINT_CASE(uint32_t, uint32_t);
2339 case UPB_DESCRIPTOR_TYPE_INT64:
2340 case UPB_DESCRIPTOR_TYPE_UINT64:
2341 VARINT_CASE(uint64_t, uint64_t);
2342 case UPB_DESCRIPTOR_TYPE_BOOL:
2343 VARINT_CASE(bool, bool);
2344 case UPB_DESCRIPTOR_TYPE_SINT32:
2345 VARINT_CASE(int32_t, upb_zzdecode_32);
2346 case UPB_DESCRIPTOR_TYPE_SINT64:
2347 VARINT_CASE(int64_t, upb_zzdecode_64);
2348 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
2349 const upb_msglayout_msginit_v1 *subm;
2350 char *submsg;
2351 void *field_mem;
2352
2353 CHK(val.size <= (size_t)(frame->limit - val.data));
2354 d->ptr -= val.size;
2355
2356 /* Create elemente message. */
2357 UPB_ASSERT(field->submsg_index != UPB_NO_SUBMSG);
2358 subm = frame->m->submsgs[field->submsg_index];
2359 UPB_ASSERT(subm);
2360
2361 submsg = upb_env_malloc(d->env, upb_msg_sizeof((upb_msglayout *)subm));
2362 CHK(submsg);
2363 submsg = upb_msg_init(submsg, (upb_msglayout*)subm,
2364 upb_arena_alloc(upb_env_arena(d->env)));
2365
2366 field_mem = upb_array_add(arr, 1);
2367 CHK(field_mem);
2368 *(void**)field_mem = submsg;
2369
2370 return upb_decode_message(
2371 d, val.data + val.size, frame->group_number, submsg, subm);
2372 }
2373 case UPB_DESCRIPTOR_TYPE_GROUP:
2374 return upb_append_unknown(d, frame, field_start);
2375 }
2376#undef VARINT_CASE
2377 UPB_UNREACHABLE();
2378}
2379
2380static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
2381 const char *field_start,
2382 const upb_msglayout_fieldinit_v1 *field) {
2383 upb_stringview val;
2384
2385 CHK(upb_decode_string(&d->ptr, frame->limit, &val));
2386
2387 if (field->label == UPB_LABEL_REPEATED) {
2388 return upb_decode_toarray(d, frame, field_start, field, val);
2389 } else {
2390 switch ((upb_descriptortype_t)field->descriptortype) {
2391 case UPB_DESCRIPTOR_TYPE_STRING:
2392 case UPB_DESCRIPTOR_TYPE_BYTES: {
2393 void *field_mem = upb_decode_prepareslot(d, frame, field);
2394 CHK(field_mem);
2395 memcpy(field_mem, &val, sizeof(val));
2396 break;
2397 }
2398 case UPB_DESCRIPTOR_TYPE_MESSAGE:
2399 CHK(val.size <= (size_t)(frame->limit - val.data));
2400 d->ptr -= val.size;
2401 CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
2402 break;
2403 default:
2404 /* TODO(haberman): should we accept the last element of a packed? */
2405 return upb_append_unknown(d, frame, field_start);
2406 }
2407 upb_decode_setpresent(frame, field);
2408 return true;
2409 }
2410}
2411
2412static const upb_msglayout_fieldinit_v1 *upb_find_field(
2413 const upb_msglayout_msginit_v1 *l, uint32_t field_number) {
2414 /* Lots of optimization opportunities here. */
2415 int i;
2416 for (i = 0; i < l->field_count; i++) {
2417 if (l->fields[i].number == field_number) {
2418 return &l->fields[i];
2419 }
2420 }
2421
2422 return NULL; /* Unknown field. */
2423}
2424
2425static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
2426 int field_number;
2427 int wire_type;
2428 const char *field_start = d->ptr;
2429 const upb_msglayout_fieldinit_v1 *field;
2430
2431 CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
2432 field = upb_find_field(frame->m, field_number);
2433
2434 if (field) {
2435 switch (wire_type) {
2436 case UPB_WIRE_TYPE_VARINT:
2437 return upb_decode_varintfield(d, frame, field_start, field);
2438 case UPB_WIRE_TYPE_32BIT:
2439 return upb_decode_32bitfield(d, frame, field_start, field);
2440 case UPB_WIRE_TYPE_64BIT:
2441 return upb_decode_64bitfield(d, frame, field_start, field);
2442 case UPB_WIRE_TYPE_DELIMITED:
2443 return upb_decode_delimitedfield(d, frame, field_start, field);
2444 case UPB_WIRE_TYPE_START_GROUP:
2445 CHK(field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
2446 return upb_decode_submsg(d, frame, frame->limit, field, field_number);
2447 case UPB_WIRE_TYPE_END_GROUP:
2448 CHK(frame->group_number == field_number)
2449 frame->limit = d->ptr;
2450 return true;
2451 default:
2452 return false;
2453 }
2454 } else {
2455 CHK(field_number != 0);
2456 return upb_skip_unknownfielddata(d, frame, field_number, wire_type);
2457 }
2458}
2459
2460static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
2461 const char *limit) {
2462 upb_decframe frame;
2463 frame.msg = NULL;
2464 frame.m = NULL;
2465 frame.group_number = field_number;
2466 frame.limit = limit;
2467
2468 while (d->ptr < frame.limit) {
2469 int wire_type;
2470 int field_number;
2471
2472 CHK(upb_decode_tag(&d->ptr, frame.limit, &field_number, &wire_type));
2473 CHK(upb_skip_unknownfielddata(d, &frame, field_number, wire_type));
2474 }
2475
2476 return true;
2477}
2478
2479static bool upb_decode_message(upb_decstate *d, const char *limit,
2480 int group_number, char *msg,
2481 const upb_msglayout_msginit_v1 *l) {
2482 upb_decframe frame;
2483 frame.group_number = group_number;
2484 frame.limit = limit;
2485 frame.msg = msg;
2486 frame.m = l;
2487
2488 while (d->ptr < frame.limit) {
2489 CHK(upb_decode_field(d, &frame));
2490 }
2491
2492 return true;
2493}
2494
2495bool upb_decode(upb_stringview buf, void *msg,
2496 const upb_msglayout_msginit_v1 *l, upb_env *env) {
2497 upb_decstate state;
2498 state.ptr = buf.data;
2499 state.env = env;
2500
2501 return upb_decode_message(&state, buf.data + buf.size, 0, msg, l);
2502}
2503
2504#undef CHK
2505
2506
2507#include <ctype.h>
2508#include <stdlib.h>
2509#include <string.h>
2510
2511typedef struct {
2512 size_t len;
2513 char str[1]; /* Null-terminated string data follows. */
2514} str_t;
2515
2516static str_t *newstr(const char *data, size_t len) {
2517 str_t *ret = upb_gmalloc(sizeof(*ret) + len);
2518 if (!ret) return NULL;
2519 ret->len = len;
2520 memcpy(ret->str, data, len);
2521 ret->str[len] = '\0';
2522 return ret;
2523}
2524
2525static void freestr(str_t *s) { upb_gfree(s); }
2526
2527/* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
2528static bool upb_isbetween(char c, char low, char high) {
2529 return c >= low && c <= high;
2530}
2531
2532static bool upb_isletter(char c) {
2533 return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
2534}
2535
2536static bool upb_isalphanum(char c) {
2537 return upb_isletter(c) || upb_isbetween(c, '0', '9');
2538}
2539
2540static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
2541 bool start = true;
2542 size_t i;
2543 for (i = 0; i < len; i++) {
2544 char c = str[i];
2545 if (c == '.') {
2546 if (start || !full) {
2547 upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
2548 return false;
2549 }
2550 start = true;
2551 } else if (start) {
2552 if (!upb_isletter(c)) {
2553 upb_status_seterrf(
2554 s, "invalid name: path components must start with a letter (%s)",
2555 str);
2556 return false;
2557 }
2558 start = false;
2559 } else {
2560 if (!upb_isalphanum(c)) {
2561 upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
2562 str);
2563 return false;
2564 }
2565 }
2566 }
2567 return !start;
2568}
2569
2570static bool upb_isoneof(const upb_refcounted *def) {
2571 return def->vtbl == &upb_oneofdef_vtbl;
2572}
2573
2574static bool upb_isfield(const upb_refcounted *def) {
2575 return def->vtbl == &upb_fielddef_vtbl;
2576}
2577
2578static const upb_oneofdef *upb_trygetoneof(const upb_refcounted *def) {
2579 return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL;
2580}
2581
2582static const upb_fielddef *upb_trygetfield(const upb_refcounted *def) {
2583 return upb_isfield(def) ? (const upb_fielddef*)def : NULL;
2584}
2585
2586
2587/* upb_def ********************************************************************/
2588
2589upb_deftype_t upb_def_type(const upb_def *d) { return d->type; }
2590
2591const char *upb_def_fullname(const upb_def *d) { return d->fullname; }
2592
2593const char *upb_def_name(const upb_def *d) {
2594 const char *p;
2595
2596 if (d->fullname == NULL) {
2597 return NULL;
2598 } else if ((p = strrchr(d->fullname, '.')) == NULL) {
2599 /* No '.' in the name, return the full string. */
2600 return d->fullname;
2601 } else {
2602 /* Return one past the last '.'. */
2603 return p + 1;
2604 }
2605}
2606
2607bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s) {
2608 UPB_ASSERT(!upb_def_isfrozen(def));
2609 if (!upb_isident(fullname, strlen(fullname), true, s)) {
2610 return false;
2611 }
2612
2613 fullname = upb_gstrdup(fullname);
2614 if (!fullname) {
2615 upb_upberr_setoom(s);
2616 return false;
2617 }
2618
2619 upb_gfree((void*)def->fullname);
2620 def->fullname = fullname;
2621 return true;
2622}
2623
2624const upb_filedef *upb_def_file(const upb_def *d) { return d->file; }
2625
2626static bool upb_def_init(upb_def *def, upb_deftype_t type,
2627 const struct upb_refcounted_vtbl *vtbl,
2628 const void *owner) {
2629 if (!upb_refcounted_init(upb_def_upcast_mutable(def), vtbl, owner)) return false;
2630 def->type = type;
2631 def->fullname = NULL;
2632 def->came_from_user = false;
2633 def->file = NULL;
2634 return true;
2635}
2636
2637static void upb_def_uninit(upb_def *def) {
2638 upb_gfree((void*)def->fullname);
2639}
2640
2641static const char *msgdef_name(const upb_msgdef *m) {
2642 const char *name = upb_def_fullname(upb_msgdef_upcast(m));
2643 return name ? name : "(anonymous)";
2644}
2645
2646static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
2647 if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
2648 upb_status_seterrmsg(s, "fielddef must have name and number set");
2649 return false;
2650 }
2651
2652 if (!f->type_is_set_) {
2653 upb_status_seterrmsg(s, "fielddef type was not initialized");
2654 return false;
2655 }
2656
2657 if (upb_fielddef_lazy(f) &&
2658 upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) {
2659 upb_status_seterrmsg(s,
2660 "only length-delimited submessage fields may be lazy");
2661 return false;
2662 }
2663
2664 if (upb_fielddef_hassubdef(f)) {
2665 const upb_def *subdef;
2666
2667 if (f->subdef_is_symbolic) {
2668 upb_status_seterrf(s, "field '%s.%s' has not been resolved",
2669 msgdef_name(f->msg.def), upb_fielddef_name(f));
2670 return false;
2671 }
2672
2673 subdef = upb_fielddef_subdef(f);
2674 if (subdef == NULL) {
2675 upb_status_seterrf(s, "field %s.%s is missing required subdef",
2676 msgdef_name(f->msg.def), upb_fielddef_name(f));
2677 return false;
2678 }
2679
2680 if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
2681 upb_status_seterrf(s,
2682 "subdef of field %s.%s is not frozen or being frozen",
2683 msgdef_name(f->msg.def), upb_fielddef_name(f));
2684 return false;
2685 }
2686 }
2687
2688 if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
2689 bool has_default_name = upb_fielddef_enumhasdefaultstr(f);
2690 bool has_default_number = upb_fielddef_enumhasdefaultint32(f);
2691
2692 /* Previously verified by upb_validate_enumdef(). */
2693 UPB_ASSERT(upb_enumdef_numvals(upb_fielddef_enumsubdef(f)) > 0);
2694
2695 /* We've already validated that we have an associated enumdef and that it
2696 * has at least one member, so at least one of these should be true.
2697 * Because if the user didn't set anything, we'll pick up the enum's
2698 * default, but if the user *did* set something we should at least pick up
2699 * the one they set (int32 or string). */
2700 UPB_ASSERT(has_default_name || has_default_number);
2701
2702 if (!has_default_name) {
2703 upb_status_seterrf(s,
2704 "enum default for field %s.%s (%d) is not in the enum",
2705 msgdef_name(f->msg.def), upb_fielddef_name(f),
2706 upb_fielddef_defaultint32(f));
2707 return false;
2708 }
2709
2710 if (!has_default_number) {
2711 upb_status_seterrf(s,
2712 "enum default for field %s.%s (%s) is not in the enum",
2713 msgdef_name(f->msg.def), upb_fielddef_name(f),
2714 upb_fielddef_defaultstr(f, NULL));
2715 return false;
2716 }
2717
2718 /* Lift the effective numeric default into the field's default slot, in case
2719 * we were only getting it "by reference" from the enumdef. */
2720 upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f));
2721 }
2722
2723 /* Ensure that MapEntry submessages only appear as repeated fields, not
2724 * optional/required (singular) fields. */
2725 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
2726 upb_fielddef_msgsubdef(f) != NULL) {
2727 const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
2728 if (upb_msgdef_mapentry(subdef) && !upb_fielddef_isseq(f)) {
2729 upb_status_seterrf(s,
2730 "Field %s refers to mapentry message but is not "
2731 "a repeated field",
2732 upb_fielddef_name(f) ? upb_fielddef_name(f) :
2733 "(unnamed)");
2734 return false;
2735 }
2736 }
2737
2738 return true;
2739}
2740
2741static bool upb_validate_enumdef(const upb_enumdef *e, upb_status *s) {
2742 if (upb_enumdef_numvals(e) == 0) {
2743 upb_status_seterrf(s, "enum %s has no members (must have at least one)",
2744 upb_enumdef_fullname(e));
2745 return false;
2746 }
2747
2748 return true;
2749}
2750
2751/* All submessage fields are lower than all other fields.
2752 * Secondly, fields are increasing in order. */
2753uint32_t field_rank(const upb_fielddef *f) {
2754 uint32_t ret = upb_fielddef_number(f);
2755 const uint32_t high_bit = 1 << 30;
2756 UPB_ASSERT(ret < high_bit);
2757 if (!upb_fielddef_issubmsg(f))
2758 ret |= high_bit;
2759 return ret;
2760}
2761
2762int cmp_fields(const void *p1, const void *p2) {
2763 const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
2764 const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
2765 return field_rank(f1) - field_rank(f2);
2766}
2767
2768static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
2769 /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
2770 * lowest indexes, but we do not publicly guarantee this. */
2771 upb_msg_field_iter j;
2772 upb_msg_oneof_iter k;
2773 int i;
2774 uint32_t selector;
2775 int n = upb_msgdef_numfields(m);
2776 upb_fielddef **fields;
2777
2778 if (n == 0) {
2779 m->selector_count = UPB_STATIC_SELECTOR_COUNT;
2780 m->submsg_field_count = 0;
2781 return true;
2782 }
2783
2784 fields = upb_gmalloc(n * sizeof(*fields));
2785 if (!fields) {
2786 upb_upberr_setoom(s);
2787 return false;
2788 }
2789
2790 m->submsg_field_count = 0;
2791 for(i = 0, upb_msg_field_begin(&j, m);
2792 !upb_msg_field_done(&j);
2793 upb_msg_field_next(&j), i++) {
2794 upb_fielddef *f = upb_msg_iter_field(&j);
2795 UPB_ASSERT(f->msg.def == m);
2796 if (!upb_validate_field(f, s)) {
2797 upb_gfree(fields);
2798 return false;
2799 }
2800 if (upb_fielddef_issubmsg(f)) {
2801 m->submsg_field_count++;
2802 }
2803 fields[i] = f;
2804 }
2805
2806 qsort(fields, n, sizeof(*fields), cmp_fields);
2807
2808 selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
2809 for (i = 0; i < n; i++) {
2810 upb_fielddef *f = fields[i];
2811 f->index_ = i;
2812 f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
2813 selector += upb_handlers_selectorcount(f);
2814 }
2815 m->selector_count = selector;
2816
2817#ifndef NDEBUG
2818 {
2819 /* Verify that all selectors for the message are distinct. */
2820#define TRY(type) \
2821 if (upb_handlers_getselector(f, type, &sel)) upb_inttable_insert(&t, sel, v);
2822
2823 upb_inttable t;
2824 upb_value v;
2825 upb_selector_t sel;
2826
2827 upb_inttable_init(&t, UPB_CTYPE_BOOL);
2828 v = upb_value_bool(true);
2829 upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
2830 upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
2831 upb_inttable_insert(&t, UPB_UNKNOWN_SELECTOR, v);
2832 for(upb_msg_field_begin(&j, m);
2833 !upb_msg_field_done(&j);
2834 upb_msg_field_next(&j)) {
2835 upb_fielddef *f = upb_msg_iter_field(&j);
2836 /* These calls will assert-fail in upb_table if the value already
2837 * exists. */
2838 TRY(UPB_HANDLER_INT32);
2839 TRY(UPB_HANDLER_INT64)
2840 TRY(UPB_HANDLER_UINT32)
2841 TRY(UPB_HANDLER_UINT64)
2842 TRY(UPB_HANDLER_FLOAT)
2843 TRY(UPB_HANDLER_DOUBLE)
2844 TRY(UPB_HANDLER_BOOL)
2845 TRY(UPB_HANDLER_STARTSTR)
2846 TRY(UPB_HANDLER_STRING)
2847 TRY(UPB_HANDLER_ENDSTR)
2848 TRY(UPB_HANDLER_STARTSUBMSG)
2849 TRY(UPB_HANDLER_ENDSUBMSG)
2850 TRY(UPB_HANDLER_STARTSEQ)
2851 TRY(UPB_HANDLER_ENDSEQ)
2852 }
2853 upb_inttable_uninit(&t);
2854 }
2855#undef TRY
2856#endif
2857
2858 for(upb_msg_oneof_begin(&k, m), i = 0;
2859 !upb_msg_oneof_done(&k);
2860 upb_msg_oneof_next(&k), i++) {
2861 upb_oneofdef *o = upb_msg_iter_oneof(&k);
2862 o->index = i;
2863 }
2864
2865 upb_gfree(fields);
2866 return true;
2867}
2868
2869bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) {
2870 size_t i;
2871
2872 /* First perform validation, in two passes so we can check that we have a
2873 * transitive closure without needing to search. */
2874 for (i = 0; i < n; i++) {
2875 upb_def *def = defs[i];
2876 if (upb_def_isfrozen(def)) {
2877 /* Could relax this requirement if it's annoying. */
2878 upb_status_seterrmsg(s, "def is already frozen");
2879 goto err;
2880 } else if (def->type == UPB_DEF_FIELD) {
2881 upb_status_seterrmsg(s, "standalone fielddefs can not be frozen");
2882 goto err;
2883 } else {
2884 /* Set now to detect transitive closure in the second pass. */
2885 def->came_from_user = true;
2886
2887 if (def->type == UPB_DEF_ENUM &&
2888 !upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
2889 goto err;
2890 }
2891 }
2892 }
2893
2894 /* Second pass of validation. Also assign selector bases and indexes, and
2895 * compact tables. */
2896 for (i = 0; i < n; i++) {
2897 upb_def *def = defs[i];
2898 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
2899 upb_enumdef *e = upb_dyncast_enumdef_mutable(def);
2900 if (m) {
2901 upb_inttable_compact(&m->itof);
2902 if (!assign_msg_indices(m, s)) {
2903 goto err;
2904 }
2905 } else if (e) {
2906 upb_inttable_compact(&e->iton);
2907 }
2908 }
2909
2910 return true;
2911
2912err:
2913 for (i = 0; i < n; i++) {
2914 upb_def *def = defs[i];
2915 def->came_from_user = false;
2916 }
2917 UPB_ASSERT(!(s && upb_ok(s)));
2918 return false;
2919}
2920
2921bool upb_def_freeze(upb_def *const* defs, size_t n, upb_status *s) {
2922 /* Def graph contains FieldDefs between each MessageDef, so double the
2923 * limit. */
2924 const size_t maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
2925
2926 if (!_upb_def_validate(defs, n, s)) {
2927 return false;
2928 }
2929
2930
2931 /* Validation all passed; freeze the objects. */
2932 return upb_refcounted_freeze((upb_refcounted *const*)defs, n, s, maxdepth);
2933}
2934
2935
2936/* upb_enumdef ****************************************************************/
2937
2938static void visitenum(const upb_refcounted *r, upb_refcounted_visit *visit,
2939 void *closure) {
2940 const upb_enumdef *e = (const upb_enumdef*)r;
2941 const upb_def *def = upb_enumdef_upcast(e);
2942 if (upb_def_file(def)) {
2943 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
2944 }
2945}
2946
2947static void freeenum(upb_refcounted *r) {
2948 upb_enumdef *e = (upb_enumdef*)r;
2949 upb_inttable_iter i;
2950 upb_inttable_begin(&i, &e->iton);
2951 for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2952 /* To clean up the upb_gstrdup() from upb_enumdef_addval(). */
2953 upb_gfree(upb_value_getcstr(upb_inttable_iter_value(&i)));
2954 }
2955 upb_strtable_uninit(&e->ntoi);
2956 upb_inttable_uninit(&e->iton);
2957 upb_def_uninit(upb_enumdef_upcast_mutable(e));
2958 upb_gfree(e);
2959}
2960
2961const struct upb_refcounted_vtbl upb_enumdef_vtbl = {&visitenum, &freeenum};
2962
2963upb_enumdef *upb_enumdef_new(const void *owner) {
2964 upb_enumdef *e = upb_gmalloc(sizeof(*e));
2965 if (!e) return NULL;
2966
2967 if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM,
2968 &upb_enumdef_vtbl, owner)) {
2969 goto err2;
2970 }
2971
2972 if (!upb_strtable_init(&e->ntoi, UPB_CTYPE_INT32)) goto err2;
2973 if (!upb_inttable_init(&e->iton, UPB_CTYPE_CSTR)) goto err1;
2974 return e;
2975
2976err1:
2977 upb_strtable_uninit(&e->ntoi);
2978err2:
2979 upb_gfree(e);
2980 return NULL;
2981}
2982
2983bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status) {
2984 upb_def *d = upb_enumdef_upcast_mutable(e);
2985 return upb_def_freeze(&d, 1, status);
2986}
2987
2988const char *upb_enumdef_fullname(const upb_enumdef *e) {
2989 return upb_def_fullname(upb_enumdef_upcast(e));
2990}
2991
2992const char *upb_enumdef_name(const upb_enumdef *e) {
2993 return upb_def_name(upb_enumdef_upcast(e));
2994}
2995
2996bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
2997 upb_status *s) {
2998 return upb_def_setfullname(upb_enumdef_upcast_mutable(e), fullname, s);
2999}
3000
3001bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
3002 upb_status *status) {
3003 char *name2;
3004
3005 if (!upb_isident(name, strlen(name), false, status)) {
3006 return false;
3007 }
3008
3009 if (upb_enumdef_ntoiz(e, name, NULL)) {
3010 upb_status_seterrf(status, "name '%s' is already defined", name);
3011 return false;
3012 }
3013
3014 if (!upb_strtable_insert(&e->ntoi, name, upb_value_int32(num))) {
3015 upb_status_seterrmsg(status, "out of memory");
3016 return false;
3017 }
3018
3019 if (!upb_inttable_lookup(&e->iton, num, NULL)) {
3020 name2 = upb_gstrdup(name);
3021 if (!name2 || !upb_inttable_insert(&e->iton, num, upb_value_cstr(name2))) {
3022 upb_status_seterrmsg(status, "out of memory");
3023 upb_strtable_remove(&e->ntoi, name, NULL);
3024 return false;
3025 }
3026 }
3027
3028 if (upb_enumdef_numvals(e) == 1) {
3029 bool ok = upb_enumdef_setdefault(e, num, NULL);
3030 UPB_ASSERT(ok);
3031 }
3032
3033 return true;
3034}
3035
3036int32_t upb_enumdef_default(const upb_enumdef *e) {
3037 UPB_ASSERT(upb_enumdef_iton(e, e->defaultval));
3038 return e->defaultval;
3039}
3040
3041bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) {
3042 UPB_ASSERT(!upb_enumdef_isfrozen(e));
3043 if (!upb_enumdef_iton(e, val)) {
3044 upb_status_seterrf(s, "number '%d' is not in the enum.", val);
3045 return false;
3046 }
3047 e->defaultval = val;
3048 return true;
3049}
3050
3051int upb_enumdef_numvals(const upb_enumdef *e) {
3052 return upb_strtable_count(&e->ntoi);
3053}
3054
3055void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
3056 /* We iterate over the ntoi table, to account for duplicate numbers. */
3057 upb_strtable_begin(i, &e->ntoi);
3058}
3059
3060void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
3061bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
3062
3063bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
3064 size_t len, int32_t *num) {
3065 upb_value v;
3066 if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
3067 return false;
3068 }
3069 if (num) *num = upb_value_getint32(v);
3070 return true;
3071}
3072
3073const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
3074 upb_value v;
3075 return upb_inttable_lookup32(&def->iton, num, &v) ?
3076 upb_value_getcstr(v) : NULL;
3077}
3078
3079const char *upb_enum_iter_name(upb_enum_iter *iter) {
3080 return upb_strtable_iter_key(iter);
3081}
3082
3083int32_t upb_enum_iter_number(upb_enum_iter *iter) {
3084 return upb_value_getint32(upb_strtable_iter_value(iter));
3085}
3086
3087
3088/* upb_fielddef ***************************************************************/
3089
3090static void upb_fielddef_init_default(upb_fielddef *f);
3091
3092static void upb_fielddef_uninit_default(upb_fielddef *f) {
3093 if (f->type_is_set_ && f->default_is_string && f->defaultval.bytes)
3094 freestr(f->defaultval.bytes);
3095}
3096
3097const char *upb_fielddef_fullname(const upb_fielddef *e) {
3098 return upb_def_fullname(upb_fielddef_upcast(e));
3099}
3100
3101static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
3102 void *closure) {
3103 const upb_fielddef *f = (const upb_fielddef*)r;
3104 const upb_def *def = upb_fielddef_upcast(f);
3105 if (upb_fielddef_containingtype(f)) {
3106 visit(r, upb_msgdef_upcast2(upb_fielddef_containingtype(f)), closure);
3107 }
3108 if (upb_fielddef_containingoneof(f)) {
3109 visit(r, upb_oneofdef_upcast(upb_fielddef_containingoneof(f)), closure);
3110 }
3111 if (upb_fielddef_subdef(f)) {
3112 visit(r, upb_def_upcast(upb_fielddef_subdef(f)), closure);
3113 }
3114 if (upb_def_file(def)) {
3115 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
3116 }
3117}
3118
3119static void freefield(upb_refcounted *r) {
3120 upb_fielddef *f = (upb_fielddef*)r;
3121 upb_fielddef_uninit_default(f);
3122 if (f->subdef_is_symbolic)
3123 upb_gfree(f->sub.name);
3124 upb_def_uninit(upb_fielddef_upcast_mutable(f));
3125 upb_gfree(f);
3126}
3127
3128static const char *enumdefaultstr(const upb_fielddef *f) {
3129 const upb_enumdef *e;
3130 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
3131 e = upb_fielddef_enumsubdef(f);
3132 if (f->default_is_string && f->defaultval.bytes) {
3133 /* Default was explicitly set as a string. */
3134 str_t *s = f->defaultval.bytes;
3135 return s->str;
3136 } else if (e) {
3137 if (!f->default_is_string) {
3138 /* Default was explicitly set as an integer; look it up in enumdef. */
3139 const char *name = upb_enumdef_iton(e, f->defaultval.sint);
3140 if (name) {
3141 return name;
3142 }
3143 } else {
3144 /* Default is completely unset; pull enumdef default. */
3145 if (upb_enumdef_numvals(e) > 0) {
3146 const char *name = upb_enumdef_iton(e, upb_enumdef_default(e));
3147 UPB_ASSERT(name);
3148 return name;
3149 }
3150 }
3151 }
3152 return NULL;
3153}
3154
3155static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) {
3156 const upb_enumdef *e;
3157 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
3158 e = upb_fielddef_enumsubdef(f);
3159 if (!f->default_is_string) {
3160 /* Default was explicitly set as an integer. */
3161 *val = f->defaultval.sint;
3162 return true;
3163 } else if (e) {
3164 if (f->defaultval.bytes) {
3165 /* Default was explicitly set as a str; try to lookup corresponding int. */
3166 str_t *s = f->defaultval.bytes;
3167 if (upb_enumdef_ntoiz(e, s->str, val)) {
3168 return true;
3169 }
3170 } else {
3171 /* Default is unset; try to pull in enumdef default. */
3172 if (upb_enumdef_numvals(e) > 0) {
3173 *val = upb_enumdef_default(e);
3174 return true;
3175 }
3176 }
3177 }
3178 return false;
3179}
3180
3181const struct upb_refcounted_vtbl upb_fielddef_vtbl = {visitfield, freefield};
3182
3183upb_fielddef *upb_fielddef_new(const void *o) {
3184 upb_fielddef *f = upb_gmalloc(sizeof(*f));
3185 if (!f) return NULL;
3186 if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD,
3187 &upb_fielddef_vtbl, o)) {
3188 upb_gfree(f);
3189 return NULL;
3190 }
3191 f->msg.def = NULL;
3192 f->sub.def = NULL;
3193 f->oneof = NULL;
3194 f->subdef_is_symbolic = false;
3195 f->msg_is_symbolic = false;
3196 f->label_ = UPB_LABEL_OPTIONAL;
3197 f->type_ = UPB_TYPE_INT32;
3198 f->number_ = 0;
3199 f->type_is_set_ = false;
3200 f->tagdelim = false;
3201 f->is_extension_ = false;
3202 f->lazy_ = false;
3203 f->packed_ = true;
3204
3205 /* For the moment we default this to UPB_INTFMT_VARIABLE, since it will work
3206 * with all integer types and is in some since more "default" since the most
3207 * normal-looking proto2 types int32/int64/uint32/uint64 use variable.
3208 *
3209 * Other options to consider:
3210 * - there is no default; users must set this manually (like type).
3211 * - default signed integers to UPB_INTFMT_ZIGZAG, since it's more likely to
3212 * be an optimal default for signed integers. */
3213 f->intfmt = UPB_INTFMT_VARIABLE;
3214 return f;
3215}
3216
3217bool upb_fielddef_typeisset(const upb_fielddef *f) {
3218 return f->type_is_set_;
3219}
3220
3221upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
3222 UPB_ASSERT(f->type_is_set_);
3223 return f->type_;
3224}
3225
3226uint32_t upb_fielddef_index(const upb_fielddef *f) {
3227 return f->index_;
3228}
3229
3230upb_label_t upb_fielddef_label(const upb_fielddef *f) {
3231 return f->label_;
3232}
3233
3234upb_intfmt_t upb_fielddef_intfmt(const upb_fielddef *f) {
3235 return f->intfmt;
3236}
3237
3238bool upb_fielddef_istagdelim(const upb_fielddef *f) {
3239 return f->tagdelim;
3240}
3241
3242uint32_t upb_fielddef_number(const upb_fielddef *f) {
3243 return f->number_;
3244}
3245
3246bool upb_fielddef_isextension(const upb_fielddef *f) {
3247 return f->is_extension_;
3248}
3249
3250bool upb_fielddef_lazy(const upb_fielddef *f) {
3251 return f->lazy_;
3252}
3253
3254bool upb_fielddef_packed(const upb_fielddef *f) {
3255 return f->packed_;
3256}
3257
3258const char *upb_fielddef_name(const upb_fielddef *f) {
3259 return upb_def_fullname(upb_fielddef_upcast(f));
3260}
3261
3262size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
3263 const char *name = upb_fielddef_name(f);
3264 size_t src, dst = 0;
3265 bool ucase_next = false;
3266
3267#define WRITE(byte) \
3268 ++dst; \
3269 if (dst < len) buf[dst - 1] = byte; \
3270 else if (dst == len) buf[dst - 1] = '\0'
3271
3272 if (!name) {
3273 WRITE('\0');
3274 return 0;
3275 }
3276
3277 /* Implement the transformation as described in the spec:
3278 * 1. upper case all letters after an underscore.
3279 * 2. remove all underscores.
3280 */
3281 for (src = 0; name[src]; src++) {
3282 if (name[src] == '_') {
3283 ucase_next = true;
3284 continue;
3285 }
3286
3287 if (ucase_next) {
3288 WRITE(toupper(name[src]));
3289 ucase_next = false;
3290 } else {
3291 WRITE(name[src]);
3292 }
3293 }
3294
3295 WRITE('\0');
3296 return dst;
3297
3298#undef WRITE
3299}
3300
3301const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
3302 return f->msg_is_symbolic ? NULL : f->msg.def;
3303}
3304
3305const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
3306 return f->oneof;
3307}
3308
3309upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) {
3310 return (upb_msgdef*)upb_fielddef_containingtype(f);
3311}
3312
3313const char *upb_fielddef_containingtypename(upb_fielddef *f) {
3314 return f->msg_is_symbolic ? f->msg.name : NULL;
3315}
3316
3317static void release_containingtype(upb_fielddef *f) {
3318 if (f->msg_is_symbolic) upb_gfree(f->msg.name);
3319}
3320
3321bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
3322 upb_status *s) {
3323 char *name_copy;
3324 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3325 if (upb_fielddef_containingtype(f)) {
3326 upb_status_seterrmsg(s, "field has already been added to a message.");
3327 return false;
3328 }
3329 /* TODO: validate name (upb_isident() doesn't quite work atm because this name
3330 * may have a leading "."). */
3331
3332 name_copy = upb_gstrdup(name);
3333 if (!name_copy) {
3334 upb_upberr_setoom(s);
3335 return false;
3336 }
3337
3338 release_containingtype(f);
3339 f->msg.name = name_copy;
3340 f->msg_is_symbolic = true;
3341 return true;
3342}
3343
3344bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) {
3345 if (upb_fielddef_containingtype(f) || upb_fielddef_containingoneof(f)) {
3346 upb_status_seterrmsg(s, "Already added to message or oneof");
3347 return false;
3348 }
3349 return upb_def_setfullname(upb_fielddef_upcast_mutable(f), name, s);
3350}
3351
3352static void chkdefaulttype(const upb_fielddef *f, upb_fieldtype_t type) {
3353 UPB_UNUSED(f);
3354 UPB_UNUSED(type);
3355 UPB_ASSERT(f->type_is_set_ && upb_fielddef_type(f) == type);
3356}
3357
3358int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
3359 chkdefaulttype(f, UPB_TYPE_INT64);
3360 return f->defaultval.sint;
3361}
3362
3363int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
3364 if (f->type_is_set_ && upb_fielddef_type(f) == UPB_TYPE_ENUM) {
3365 int32_t val;
3366 bool ok = enumdefaultint32(f, &val);
3367 UPB_ASSERT(ok);
3368 return val;
3369 } else {
3370 chkdefaulttype(f, UPB_TYPE_INT32);
3371 return f->defaultval.sint;
3372 }
3373}
3374
3375uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
3376 chkdefaulttype(f, UPB_TYPE_UINT64);
3377 return f->defaultval.uint;
3378}
3379
3380uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
3381 chkdefaulttype(f, UPB_TYPE_UINT32);
3382 return f->defaultval.uint;
3383}
3384
3385bool upb_fielddef_defaultbool(const upb_fielddef *f) {
3386 chkdefaulttype(f, UPB_TYPE_BOOL);
3387 return f->defaultval.uint;
3388}
3389
3390float upb_fielddef_defaultfloat(const upb_fielddef *f) {
3391 chkdefaulttype(f, UPB_TYPE_FLOAT);
3392 return f->defaultval.flt;
3393}
3394
3395double upb_fielddef_defaultdouble(const upb_fielddef *f) {
3396 chkdefaulttype(f, UPB_TYPE_DOUBLE);
3397 return f->defaultval.dbl;
3398}
3399
3400const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
3401 UPB_ASSERT(f->type_is_set_);
3402 UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING ||
3403 upb_fielddef_type(f) == UPB_TYPE_BYTES ||
3404 upb_fielddef_type(f) == UPB_TYPE_ENUM);
3405
3406 if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
3407 const char *ret = enumdefaultstr(f);
3408 UPB_ASSERT(ret);
3409 /* Enum defaults can't have embedded NULLs. */
3410 if (len) *len = strlen(ret);
3411 return ret;
3412 }
3413
3414 if (f->default_is_string) {
3415 str_t *str = f->defaultval.bytes;
3416 if (len) *len = str->len;
3417 return str->str;
3418 }
3419
3420 return NULL;
3421}
3422
3423static void upb_fielddef_init_default(upb_fielddef *f) {
3424 f->default_is_string = false;
3425 switch (upb_fielddef_type(f)) {
3426 case UPB_TYPE_DOUBLE: f->defaultval.dbl = 0; break;
3427 case UPB_TYPE_FLOAT: f->defaultval.flt = 0; break;
3428 case UPB_TYPE_INT32:
3429 case UPB_TYPE_INT64: f->defaultval.sint = 0; break;
3430 case UPB_TYPE_UINT64:
3431 case UPB_TYPE_UINT32:
3432 case UPB_TYPE_BOOL: f->defaultval.uint = 0; break;
3433 case UPB_TYPE_STRING:
3434 case UPB_TYPE_BYTES:
3435 f->defaultval.bytes = newstr("", 0);
3436 f->default_is_string = true;
3437 break;
3438 case UPB_TYPE_MESSAGE: break;
3439 case UPB_TYPE_ENUM:
3440 /* This is our special sentinel that indicates "not set" for an enum. */
3441 f->default_is_string = true;
3442 f->defaultval.bytes = NULL;
3443 break;
3444 }
3445}
3446
3447const upb_def *upb_fielddef_subdef(const upb_fielddef *f) {
3448 return f->subdef_is_symbolic ? NULL : f->sub.def;
3449}
3450
3451const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
3452 const upb_def *def = upb_fielddef_subdef(f);
3453 return def ? upb_dyncast_msgdef(def) : NULL;
3454}
3455
3456const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
3457 const upb_def *def = upb_fielddef_subdef(f);
3458 return def ? upb_dyncast_enumdef(def) : NULL;
3459}
3460
3461upb_def *upb_fielddef_subdef_mutable(upb_fielddef *f) {
3462 return (upb_def*)upb_fielddef_subdef(f);
3463}
3464
3465const char *upb_fielddef_subdefname(const upb_fielddef *f) {
3466 if (f->subdef_is_symbolic) {
3467 return f->sub.name;
3468 } else if (f->sub.def) {
3469 return upb_def_fullname(f->sub.def);
3470 } else {
3471 return NULL;
3472 }
3473}
3474
3475bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
3476 if (upb_fielddef_containingtype(f)) {
3477 upb_status_seterrmsg(
3478 s, "cannot change field number after adding to a message");
3479 return false;
3480 }
3481 if (number == 0 || number > UPB_MAX_FIELDNUMBER) {
3482 upb_status_seterrf(s, "invalid field number (%u)", number);
3483 return false;
3484 }
3485 f->number_ = number;
3486 return true;
3487}
3488
3489void upb_fielddef_settype(upb_fielddef *f, upb_fieldtype_t type) {
3490 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3491 UPB_ASSERT(upb_fielddef_checktype(type));
3492 upb_fielddef_uninit_default(f);
3493 f->type_ = type;
3494 f->type_is_set_ = true;
3495 upb_fielddef_init_default(f);
3496}
3497
3498void upb_fielddef_setdescriptortype(upb_fielddef *f, int type) {
3499 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3500 switch (type) {
3501 case UPB_DESCRIPTOR_TYPE_DOUBLE:
3502 upb_fielddef_settype(f, UPB_TYPE_DOUBLE);
3503 break;
3504 case UPB_DESCRIPTOR_TYPE_FLOAT:
3505 upb_fielddef_settype(f, UPB_TYPE_FLOAT);
3506 break;
3507 case UPB_DESCRIPTOR_TYPE_INT64:
3508 case UPB_DESCRIPTOR_TYPE_SFIXED64:
3509 case UPB_DESCRIPTOR_TYPE_SINT64:
3510 upb_fielddef_settype(f, UPB_TYPE_INT64);
3511 break;
3512 case UPB_DESCRIPTOR_TYPE_UINT64:
3513 case UPB_DESCRIPTOR_TYPE_FIXED64:
3514 upb_fielddef_settype(f, UPB_TYPE_UINT64);
3515 break;
3516 case UPB_DESCRIPTOR_TYPE_INT32:
3517 case UPB_DESCRIPTOR_TYPE_SFIXED32:
3518 case UPB_DESCRIPTOR_TYPE_SINT32:
3519 upb_fielddef_settype(f, UPB_TYPE_INT32);
3520 break;
3521 case UPB_DESCRIPTOR_TYPE_UINT32:
3522 case UPB_DESCRIPTOR_TYPE_FIXED32:
3523 upb_fielddef_settype(f, UPB_TYPE_UINT32);
3524 break;
3525 case UPB_DESCRIPTOR_TYPE_BOOL:
3526 upb_fielddef_settype(f, UPB_TYPE_BOOL);
3527 break;
3528 case UPB_DESCRIPTOR_TYPE_STRING:
3529 upb_fielddef_settype(f, UPB_TYPE_STRING);
3530 break;
3531 case UPB_DESCRIPTOR_TYPE_BYTES:
3532 upb_fielddef_settype(f, UPB_TYPE_BYTES);
3533 break;
3534 case UPB_DESCRIPTOR_TYPE_GROUP:
3535 case UPB_DESCRIPTOR_TYPE_MESSAGE:
3536 upb_fielddef_settype(f, UPB_TYPE_MESSAGE);
3537 break;
3538 case UPB_DESCRIPTOR_TYPE_ENUM:
3539 upb_fielddef_settype(f, UPB_TYPE_ENUM);
3540 break;
3541 default: UPB_ASSERT(false);
3542 }
3543
3544 if (type == UPB_DESCRIPTOR_TYPE_FIXED64 ||
3545 type == UPB_DESCRIPTOR_TYPE_FIXED32 ||
3546 type == UPB_DESCRIPTOR_TYPE_SFIXED64 ||
3547 type == UPB_DESCRIPTOR_TYPE_SFIXED32) {
3548 upb_fielddef_setintfmt(f, UPB_INTFMT_FIXED);
3549 } else if (type == UPB_DESCRIPTOR_TYPE_SINT64 ||
3550 type == UPB_DESCRIPTOR_TYPE_SINT32) {
3551 upb_fielddef_setintfmt(f, UPB_INTFMT_ZIGZAG);
3552 } else {
3553 upb_fielddef_setintfmt(f, UPB_INTFMT_VARIABLE);
3554 }
3555
3556 upb_fielddef_settagdelim(f, type == UPB_DESCRIPTOR_TYPE_GROUP);
3557}
3558
3559upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
3560 switch (upb_fielddef_type(f)) {
3561 case UPB_TYPE_FLOAT: return UPB_DESCRIPTOR_TYPE_FLOAT;
3562 case UPB_TYPE_DOUBLE: return UPB_DESCRIPTOR_TYPE_DOUBLE;
3563 case UPB_TYPE_BOOL: return UPB_DESCRIPTOR_TYPE_BOOL;
3564 case UPB_TYPE_STRING: return UPB_DESCRIPTOR_TYPE_STRING;
3565 case UPB_TYPE_BYTES: return UPB_DESCRIPTOR_TYPE_BYTES;
3566 case UPB_TYPE_ENUM: return UPB_DESCRIPTOR_TYPE_ENUM;
3567 case UPB_TYPE_INT32:
3568 switch (upb_fielddef_intfmt(f)) {
3569 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT32;
3570 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED32;
3571 case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT32;
3572 }
3573 case UPB_TYPE_INT64:
3574 switch (upb_fielddef_intfmt(f)) {
3575 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT64;
3576 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED64;
3577 case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT64;
3578 }
3579 case UPB_TYPE_UINT32:
3580 switch (upb_fielddef_intfmt(f)) {
3581 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT32;
3582 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED32;
3583 case UPB_INTFMT_ZIGZAG: return -1;
3584 }
3585 case UPB_TYPE_UINT64:
3586 switch (upb_fielddef_intfmt(f)) {
3587 case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT64;
3588 case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED64;
3589 case UPB_INTFMT_ZIGZAG: return -1;
3590 }
3591 case UPB_TYPE_MESSAGE:
3592 return upb_fielddef_istagdelim(f) ?
3593 UPB_DESCRIPTOR_TYPE_GROUP : UPB_DESCRIPTOR_TYPE_MESSAGE;
3594 }
3595 return 0;
3596}
3597
3598void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension) {
3599 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3600 f->is_extension_ = is_extension;
3601}
3602
3603void upb_fielddef_setlazy(upb_fielddef *f, bool lazy) {
3604 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3605 f->lazy_ = lazy;
3606}
3607
3608void upb_fielddef_setpacked(upb_fielddef *f, bool packed) {
3609 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3610 f->packed_ = packed;
3611}
3612
3613void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label) {
3614 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3615 UPB_ASSERT(upb_fielddef_checklabel(label));
3616 f->label_ = label;
3617}
3618
3619void upb_fielddef_setintfmt(upb_fielddef *f, upb_intfmt_t fmt) {
3620 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3621 UPB_ASSERT(upb_fielddef_checkintfmt(fmt));
3622 f->intfmt = fmt;
3623}
3624
3625void upb_fielddef_settagdelim(upb_fielddef *f, bool tag_delim) {
3626 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3627 f->tagdelim = tag_delim;
3628 f->tagdelim = tag_delim;
3629}
3630
3631static bool checksetdefault(upb_fielddef *f, upb_fieldtype_t type) {
3632 if (!f->type_is_set_ || upb_fielddef_isfrozen(f) ||
3633 upb_fielddef_type(f) != type) {
3634 UPB_ASSERT(false);
3635 return false;
3636 }
3637 if (f->default_is_string) {
3638 str_t *s = f->defaultval.bytes;
3639 UPB_ASSERT(s || type == UPB_TYPE_ENUM);
3640 if (s) freestr(s);
3641 }
3642 f->default_is_string = false;
3643 return true;
3644}
3645
3646void upb_fielddef_setdefaultint64(upb_fielddef *f, int64_t value) {
3647 if (checksetdefault(f, UPB_TYPE_INT64))
3648 f->defaultval.sint = value;
3649}
3650
3651void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t value) {
3652 if ((upb_fielddef_type(f) == UPB_TYPE_ENUM &&
3653 checksetdefault(f, UPB_TYPE_ENUM)) ||
3654 checksetdefault(f, UPB_TYPE_INT32)) {
3655 f->defaultval.sint = value;
3656 }
3657}
3658
3659void upb_fielddef_setdefaultuint64(upb_fielddef *f, uint64_t value) {
3660 if (checksetdefault(f, UPB_TYPE_UINT64))
3661 f->defaultval.uint = value;
3662}
3663
3664void upb_fielddef_setdefaultuint32(upb_fielddef *f, uint32_t value) {
3665 if (checksetdefault(f, UPB_TYPE_UINT32))
3666 f->defaultval.uint = value;
3667}
3668
3669void upb_fielddef_setdefaultbool(upb_fielddef *f, bool value) {
3670 if (checksetdefault(f, UPB_TYPE_BOOL))
3671 f->defaultval.uint = value;
3672}
3673
3674void upb_fielddef_setdefaultfloat(upb_fielddef *f, float value) {
3675 if (checksetdefault(f, UPB_TYPE_FLOAT))
3676 f->defaultval.flt = value;
3677}
3678
3679void upb_fielddef_setdefaultdouble(upb_fielddef *f, double value) {
3680 if (checksetdefault(f, UPB_TYPE_DOUBLE))
3681 f->defaultval.dbl = value;
3682}
3683
3684bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
3685 upb_status *s) {
3686 str_t *str2;
3687 UPB_ASSERT(upb_fielddef_isstring(f) || f->type_ == UPB_TYPE_ENUM);
3688 if (f->type_ == UPB_TYPE_ENUM && !upb_isident(str, len, false, s))
3689 return false;
3690
3691 if (f->default_is_string) {
3692 str_t *s = f->defaultval.bytes;
3693 UPB_ASSERT(s || f->type_ == UPB_TYPE_ENUM);
3694 if (s) freestr(s);
3695 } else {
3696 UPB_ASSERT(f->type_ == UPB_TYPE_ENUM);
3697 }
3698
3699 str2 = newstr(str, len);
3700 f->defaultval.bytes = str2;
3701 f->default_is_string = true;
3702 return true;
3703}
3704
3705void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
3706 upb_status *s) {
3707 UPB_ASSERT(f->type_is_set_);
3708 upb_fielddef_setdefaultstr(f, str, str ? strlen(str) : 0, s);
3709}
3710
3711bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f) {
3712 int32_t val;
3713 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
3714 return enumdefaultint32(f, &val);
3715}
3716
3717bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f) {
3718 UPB_ASSERT(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
3719 return enumdefaultstr(f) != NULL;
3720}
3721
3722static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
3723 upb_status *s) {
3724 if (f->type_ == UPB_TYPE_MESSAGE) {
3725 if (upb_dyncast_msgdef(subdef)) return true;
3726 upb_status_seterrmsg(s, "invalid subdef type for this submessage field");
3727 return false;
3728 } else if (f->type_ == UPB_TYPE_ENUM) {
3729 if (upb_dyncast_enumdef(subdef)) return true;
3730 upb_status_seterrmsg(s, "invalid subdef type for this enum field");
3731 return false;
3732 } else {
3733 upb_status_seterrmsg(s, "only message and enum fields can have a subdef");
3734 return false;
3735 }
3736}
3737
3738static void release_subdef(upb_fielddef *f) {
3739 if (f->subdef_is_symbolic) {
3740 upb_gfree(f->sub.name);
3741 } else if (f->sub.def) {
3742 upb_unref2(f->sub.def, f);
3743 }
3744}
3745
3746bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef,
3747 upb_status *s) {
3748 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3749 UPB_ASSERT(upb_fielddef_hassubdef(f));
3750 if (subdef && !upb_subdef_typecheck(f, subdef, s)) return false;
3751 release_subdef(f);
3752 f->sub.def = subdef;
3753 f->subdef_is_symbolic = false;
3754 if (f->sub.def) upb_ref2(f->sub.def, f);
3755 return true;
3756}
3757
3758bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef,
3759 upb_status *s) {
3760 return upb_fielddef_setsubdef(f, upb_msgdef_upcast(subdef), s);
3761}
3762
3763bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef,
3764 upb_status *s) {
3765 return upb_fielddef_setsubdef(f, upb_enumdef_upcast(subdef), s);
3766}
3767
3768bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name,
3769 upb_status *s) {
3770 char *name_copy;
3771 UPB_ASSERT(!upb_fielddef_isfrozen(f));
3772 if (!upb_fielddef_hassubdef(f)) {
3773 upb_status_seterrmsg(s, "field type does not accept a subdef");
3774 return false;
3775 }
3776
3777 name_copy = upb_gstrdup(name);
3778 if (!name_copy) {
3779 upb_upberr_setoom(s);
3780 return false;
3781 }
3782
3783 /* TODO: validate name (upb_isident() doesn't quite work atm because this name
3784 * may have a leading "."). */
3785 release_subdef(f);
3786 f->sub.name = name_copy;
3787 f->subdef_is_symbolic = true;
3788 return true;
3789}
3790
3791bool upb_fielddef_issubmsg(const upb_fielddef *f) {
3792 return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
3793}
3794
3795bool upb_fielddef_isstring(const upb_fielddef *f) {
3796 return upb_fielddef_type(f) == UPB_TYPE_STRING ||
3797 upb_fielddef_type(f) == UPB_TYPE_BYTES;
3798}
3799
3800bool upb_fielddef_isseq(const upb_fielddef *f) {
3801 return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
3802}
3803
3804bool upb_fielddef_isprimitive(const upb_fielddef *f) {
3805 return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
3806}
3807
3808bool upb_fielddef_ismap(const upb_fielddef *f) {
3809 return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
3810 upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
3811}
3812
3813bool upb_fielddef_haspresence(const upb_fielddef *f) {
3814 if (upb_fielddef_isseq(f)) return false;
3815 if (upb_fielddef_issubmsg(f)) return true;
3816
3817 /* Primitive field: return true unless there is a message that specifies
3818 * presence should not exist. */
3819 if (f->msg_is_symbolic || !f->msg.def) return true;
3820 return f->msg.def->syntax == UPB_SYNTAX_PROTO2;
3821}
3822
3823bool upb_fielddef_hassubdef(const upb_fielddef *f) {
3824 return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
3825}
3826
3827static bool between(int32_t x, int32_t low, int32_t high) {
3828 return x >= low && x <= high;
3829}
3830
3831bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
3832bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
3833bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
3834
3835bool upb_fielddef_checkdescriptortype(int32_t type) {
3836 return between(type, 1, 18);
3837}
3838
3839/* upb_msgdef *****************************************************************/
3840
3841static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit,
3842 void *closure) {
3843 upb_msg_oneof_iter o;
3844 const upb_msgdef *m = (const upb_msgdef*)r;
3845 const upb_def *def = upb_msgdef_upcast(m);
3846 upb_msg_field_iter i;
3847 for(upb_msg_field_begin(&i, m);
3848 !upb_msg_field_done(&i);
3849 upb_msg_field_next(&i)) {
3850 upb_fielddef *f = upb_msg_iter_field(&i);
3851 visit(r, upb_fielddef_upcast2(f), closure);
3852 }
3853 for(upb_msg_oneof_begin(&o, m);
3854 !upb_msg_oneof_done(&o);
3855 upb_msg_oneof_next(&o)) {
3856 upb_oneofdef *f = upb_msg_iter_oneof(&o);
3857 visit(r, upb_oneofdef_upcast(f), closure);
3858 }
3859 if (upb_def_file(def)) {
3860 visit(r, upb_filedef_upcast(upb_def_file(def)), closure);
3861 }
3862}
3863
3864static void freemsg(upb_refcounted *r) {
3865 upb_msgdef *m = (upb_msgdef*)r;
3866 upb_strtable_uninit(&m->ntof);
3867 upb_inttable_uninit(&m->itof);
3868 upb_def_uninit(upb_msgdef_upcast_mutable(m));
3869 upb_gfree(m);
3870}
3871
3872const struct upb_refcounted_vtbl upb_msgdef_vtbl = {visitmsg, freemsg};
3873
3874upb_msgdef *upb_msgdef_new(const void *owner) {
3875 upb_msgdef *m = upb_gmalloc(sizeof(*m));
3876 if (!m) return NULL;
3877
3878 if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &upb_msgdef_vtbl,
3879 owner)) {
3880 goto err2;
3881 }
3882
3883 if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err2;
3884 if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err1;
3885 m->map_entry = false;
3886 m->syntax = UPB_SYNTAX_PROTO2;
3887 return m;
3888
3889err1:
3890 upb_inttable_uninit(&m->itof);
3891err2:
3892 upb_gfree(m);
3893 return NULL;
3894}
3895
3896bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) {
3897 upb_def *d = upb_msgdef_upcast_mutable(m);
3898 return upb_def_freeze(&d, 1, status);
3899}
3900
3901const char *upb_msgdef_fullname(const upb_msgdef *m) {
3902 return upb_def_fullname(upb_msgdef_upcast(m));
3903}
3904
3905const char *upb_msgdef_name(const upb_msgdef *m) {
3906 return upb_def_name(upb_msgdef_upcast(m));
3907}
3908
3909bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
3910 upb_status *s) {
3911 return upb_def_setfullname(upb_msgdef_upcast_mutable(m), fullname, s);
3912}
3913
3914bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax) {
3915 if (syntax != UPB_SYNTAX_PROTO2 && syntax != UPB_SYNTAX_PROTO3) {
3916 return false;
3917 }
3918
3919 m->syntax = syntax;
3920 return true;
3921}
3922
3923upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
3924 return m->syntax;
3925}
3926
3927/* Helper: check that the field |f| is safe to add to msgdef |m|. Set an error
3928 * on status |s| and return false if not. */
3929static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
3930 upb_status *s) {
3931 if (upb_fielddef_containingtype(f) != NULL) {
3932 upb_status_seterrmsg(s, "fielddef already belongs to a message");
3933 return false;
3934 } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
3935 upb_status_seterrmsg(s, "field name or number were not set");
3936 return false;
3937 } else if (upb_msgdef_itof(m, upb_fielddef_number(f))) {
3938 upb_status_seterrmsg(s, "duplicate field number");
3939 return false;
3940 } else if (upb_strtable_lookup(&m->ntof, upb_fielddef_name(f), NULL)) {
3941 upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
3942 return false;
3943 }
3944 return true;
3945}
3946
3947static void add_field(upb_msgdef *m, upb_fielddef *f, const void *ref_donor) {
3948 release_containingtype(f);
3949 f->msg.def = m;
3950 f->msg_is_symbolic = false;
3951 upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
3952 upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
3953 upb_ref2(f, m);
3954 upb_ref2(m, f);
3955 if (ref_donor) upb_fielddef_unref(f, ref_donor);
3956}
3957
3958bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
3959 upb_status *s) {
3960 /* TODO: extensions need to have a separate namespace, because proto2 allows a
3961 * top-level extension (ie. one not in any package) to have the same name as a
3962 * field from the message.
3963 *
3964 * This also implies that there needs to be a separate lookup-by-name method
3965 * for extensions. It seems desirable for iteration to return both extensions
3966 * and non-extensions though.
3967 *
3968 * We also need to validate that the field number is in an extension range iff
3969 * it is an extension.
3970 *
3971 * This method is idempotent. Check if |f| is already part of this msgdef and
3972 * return immediately if so. */
3973 if (upb_fielddef_containingtype(f) == m) {
3974 if (ref_donor) upb_fielddef_unref(f, ref_donor);
3975 return true;
3976 }
3977
3978 /* Check constraints for all fields before performing any action. */
3979 if (!check_field_add(m, f, s)) {
3980 return false;
3981 } else if (upb_fielddef_containingoneof(f) != NULL) {
3982 /* Fields in a oneof can only be added by adding the oneof to the msgdef. */
3983 upb_status_seterrmsg(s, "fielddef is part of a oneof");
3984 return false;
3985 }
3986
3987 /* Constraint checks ok, perform the action. */
3988 add_field(m, f, ref_donor);
3989 return true;
3990}
3991
3992bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
3993 upb_status *s) {
3994 upb_oneof_iter it;
3995
3996 /* Check various conditions that would prevent this oneof from being added. */
3997 if (upb_oneofdef_containingtype(o)) {
3998 upb_status_seterrmsg(s, "oneofdef already belongs to a message");
3999 return false;
4000 } else if (upb_oneofdef_name(o) == NULL) {
4001 upb_status_seterrmsg(s, "oneofdef name was not set");
4002 return false;
4003 } else if (upb_strtable_lookup(&m->ntof, upb_oneofdef_name(o), NULL)) {
4004 upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
4005 return false;
4006 }
4007
4008 /* Check that all of the oneof's fields do not conflict with names or numbers
4009 * of fields already in the message. */
4010 for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
4011 const upb_fielddef *f = upb_oneof_iter_field(&it);
4012 if (!check_field_add(m, f, s)) {
4013 return false;
4014 }
4015 }
4016
4017 /* Everything checks out -- commit now. */
4018
4019 /* Add oneof itself first. */
4020 o->parent = m;
4021 upb_strtable_insert(&m->ntof, upb_oneofdef_name(o), upb_value_ptr(o));
4022 upb_ref2(o, m);
4023 upb_ref2(m, o);
4024
4025 /* Add each field of the oneof directly to the msgdef. */
4026 for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
4027 upb_fielddef *f = upb_oneof_iter_field(&it);
4028 add_field(m, f, NULL);
4029 }
4030
4031 if (ref_donor) upb_oneofdef_unref(o, ref_donor);
4032
4033 return true;
4034}
4035
4036const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
4037 upb_value val;
4038 return upb_inttable_lookup32(&m->itof, i, &val) ?
4039 upb_value_getptr(val) : NULL;
4040}
4041
4042const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
4043 size_t len) {
4044 upb_value val;
4045
4046 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4047 return NULL;
4048 }
4049
4050 return upb_trygetfield(upb_value_getptr(val));
4051}
4052
4053const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
4054 size_t len) {
4055 upb_value val;
4056
4057 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4058 return NULL;
4059 }
4060
4061 return upb_trygetoneof(upb_value_getptr(val));
4062}
4063
4064bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
4065 const upb_fielddef **f, const upb_oneofdef **o) {
4066 upb_value val;
4067
4068 if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
4069 return false;
4070 }
4071
4072 *o = upb_trygetoneof(upb_value_getptr(val));
4073 *f = upb_trygetfield(upb_value_getptr(val));
4074 UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */
4075 return true;
4076}
4077
4078int upb_msgdef_numfields(const upb_msgdef *m) {
4079 /* The number table contains only fields. */
4080 return upb_inttable_count(&m->itof);
4081}
4082
4083int upb_msgdef_numoneofs(const upb_msgdef *m) {
4084 /* The name table includes oneofs, and the number table does not. */
4085 return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
4086}
4087
4088void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) {
4089 UPB_ASSERT(!upb_msgdef_isfrozen(m));
4090 m->map_entry = map_entry;
4091}
4092
4093bool upb_msgdef_mapentry(const upb_msgdef *m) {
4094 return m->map_entry;
4095}
4096
4097void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
4098 upb_inttable_begin(iter, &m->itof);
4099}
4100
4101void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
4102
4103bool upb_msg_field_done(const upb_msg_field_iter *iter) {
4104 return upb_inttable_done(iter);
4105}
4106
4107upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
4108 return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
4109}
4110
4111void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
4112 upb_inttable_iter_setdone(iter);
4113}
4114
4115void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
4116 upb_strtable_begin(iter, &m->ntof);
4117 /* We need to skip past any initial fields. */
4118 while (!upb_strtable_done(iter) &&
4119 !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter)))) {
4120 upb_strtable_next(iter);
4121 }
4122}
4123
4124void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
4125 /* We need to skip past fields to return only oneofs. */
4126 do {
4127 upb_strtable_next(iter);
4128 } while (!upb_strtable_done(iter) &&
4129 !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter))));
4130}
4131
4132bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
4133 return upb_strtable_done(iter);
4134}
4135
4136upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
4137 return (upb_oneofdef*)upb_value_getptr(upb_strtable_iter_value(iter));
4138}
4139
4140void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
4141 upb_strtable_iter_setdone(iter);
4142}
4143
4144/* upb_oneofdef ***************************************************************/
4145
4146static void visitoneof(const upb_refcounted *r, upb_refcounted_visit *visit,
4147 void *closure) {
4148 const upb_oneofdef *o = (const upb_oneofdef*)r;
4149 upb_oneof_iter i;
4150 for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
4151 const upb_fielddef *f = upb_oneof_iter_field(&i);
4152 visit(r, upb_fielddef_upcast2(f), closure);
4153 }
4154 if (o->parent) {
4155 visit(r, upb_msgdef_upcast2(o->parent), closure);
4156 }
4157}
4158
4159static void freeoneof(upb_refcounted *r) {
4160 upb_oneofdef *o = (upb_oneofdef*)r;
4161 upb_strtable_uninit(&o->ntof);
4162 upb_inttable_uninit(&o->itof);
4163 upb_gfree((void*)o->name);
4164 upb_gfree(o);
4165}
4166
4167const struct upb_refcounted_vtbl upb_oneofdef_vtbl = {visitoneof, freeoneof};
4168
4169upb_oneofdef *upb_oneofdef_new(const void *owner) {
4170 upb_oneofdef *o = upb_gmalloc(sizeof(*o));
4171
4172 if (!o) {
4173 return NULL;
4174 }
4175
4176 o->parent = NULL;
4177 o->name = NULL;
4178
4179 if (!upb_refcounted_init(upb_oneofdef_upcast_mutable(o), &upb_oneofdef_vtbl,
4180 owner)) {
4181 goto err2;
4182 }
4183
4184 if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2;
4185 if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1;
4186
4187 return o;
4188
4189err1:
4190 upb_inttable_uninit(&o->itof);
4191err2:
4192 upb_gfree(o);
4193 return NULL;
4194}
4195
4196const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; }
4197
4198bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) {
4199 UPB_ASSERT(!upb_oneofdef_isfrozen(o));
4200 if (upb_oneofdef_containingtype(o)) {
4201 upb_status_seterrmsg(s, "oneof already added to a message");
4202 return false;
4203 }
4204
4205 if (!upb_isident(name, strlen(name), true, s)) {
4206 return false;
4207 }
4208
4209 name = upb_gstrdup(name);
4210 if (!name) {
4211 upb_status_seterrmsg(s, "One of memory");
4212 return false;
4213 }
4214
4215 upb_gfree((void*)o->name);
4216 o->name = name;
4217 return true;
4218}
4219
4220const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
4221 return o->parent;
4222}
4223
4224int upb_oneofdef_numfields(const upb_oneofdef *o) {
4225 return upb_strtable_count(&o->ntof);
4226}
4227
4228uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
4229 return o->index;
4230}
4231
4232bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f,
4233 const void *ref_donor,
4234 upb_status *s) {
4235 UPB_ASSERT(!upb_oneofdef_isfrozen(o));
4236 UPB_ASSERT(!o->parent || !upb_msgdef_isfrozen(o->parent));
4237
4238 /* This method is idempotent. Check if |f| is already part of this oneofdef
4239 * and return immediately if so. */
4240 if (upb_fielddef_containingoneof(f) == o) {
4241 return true;
4242 }
4243
4244 /* The field must have an OPTIONAL label. */
4245 if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
4246 upb_status_seterrmsg(s, "fields in oneof must have OPTIONAL label");
4247 return false;
4248 }
4249
4250 /* Check that no field with this name or number exists already in the oneof.
4251 * Also check that the field is not already part of a oneof. */
4252 if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
4253 upb_status_seterrmsg(s, "field name or number were not set");
4254 return false;
4255 } else if (upb_oneofdef_itof(o, upb_fielddef_number(f)) ||
4256 upb_oneofdef_ntofz(o, upb_fielddef_name(f))) {
4257 upb_status_seterrmsg(s, "duplicate field name or number");
4258 return false;
4259 } else if (upb_fielddef_containingoneof(f) != NULL) {
4260 upb_status_seterrmsg(s, "fielddef already belongs to a oneof");
4261 return false;
4262 }
4263
4264 /* We allow adding a field to the oneof either if the field is not part of a
4265 * msgdef, or if it is and we are also part of the same msgdef. */
4266 if (o->parent == NULL) {
4267 /* If we're not in a msgdef, the field cannot be either. Otherwise we would
4268 * need to magically add this oneof to a msgdef to remain consistent, which
4269 * is surprising behavior. */
4270 if (upb_fielddef_containingtype(f) != NULL) {
4271 upb_status_seterrmsg(s, "fielddef already belongs to a message, but "
4272 "oneof does not");
4273 return false;
4274 }
4275 } else {
4276 /* If we're in a msgdef, the user can add fields that either aren't in any
4277 * msgdef (in which case they're added to our msgdef) or already a part of
4278 * our msgdef. */
4279 if (upb_fielddef_containingtype(f) != NULL &&
4280 upb_fielddef_containingtype(f) != o->parent) {
4281 upb_status_seterrmsg(s, "fielddef belongs to a different message "
4282 "than oneof");
4283 return false;
4284 }
4285 }
4286
4287 /* Commit phase. First add the field to our parent msgdef, if any, because
4288 * that may fail; then add the field to our own tables. */
4289
4290 if (o->parent != NULL && upb_fielddef_containingtype(f) == NULL) {
4291 if (!upb_msgdef_addfield((upb_msgdef*)o->parent, f, NULL, s)) {
4292 return false;
4293 }
4294 }
4295
4296 release_containingtype(f);
4297 f->oneof = o;
4298 upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f));
4299 upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f));
4300 upb_ref2(f, o);
4301 upb_ref2(o, f);
4302 if (ref_donor) upb_fielddef_unref(f, ref_donor);
4303
4304 return true;
4305}
4306
4307const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
4308 const char *name, size_t length) {
4309 upb_value val;
4310 return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
4311 upb_value_getptr(val) : NULL;
4312}
4313
4314const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
4315 upb_value val;
4316 return upb_inttable_lookup32(&o->itof, num, &val) ?
4317 upb_value_getptr(val) : NULL;
4318}
4319
4320void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
4321 upb_inttable_begin(iter, &o->itof);
4322}
4323
4324void upb_oneof_next(upb_oneof_iter *iter) {
4325 upb_inttable_next(iter);
4326}
4327
4328bool upb_oneof_done(upb_oneof_iter *iter) {
4329 return upb_inttable_done(iter);
4330}
4331
4332upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
4333 return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
4334}
4335
4336void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
4337 upb_inttable_iter_setdone(iter);
4338}
4339
4340/* upb_filedef ****************************************************************/
4341
4342static void visitfiledef(const upb_refcounted *r, upb_refcounted_visit *visit,
4343 void *closure) {
4344 const upb_filedef *f = (const upb_filedef*)r;
4345 size_t i;
4346
4347 for(i = 0; i < upb_filedef_defcount(f); i++) {
4348 visit(r, upb_def_upcast(upb_filedef_def(f, i)), closure);
4349 }
4350}
4351
4352static void freefiledef(upb_refcounted *r) {
4353 upb_filedef *f = (upb_filedef*)r;
4354 size_t i;
4355
4356 for(i = 0; i < upb_filedef_depcount(f); i++) {
4357 upb_filedef_unref(upb_filedef_dep(f, i), f);
4358 }
4359
4360 upb_inttable_uninit(&f->defs);
4361 upb_inttable_uninit(&f->deps);
4362 upb_gfree((void*)f->name);
4363 upb_gfree((void*)f->package);
4364 upb_gfree((void*)f->phpprefix);
4365 upb_gfree((void*)f->phpnamespace);
4366 upb_gfree(f);
4367}
4368
4369const struct upb_refcounted_vtbl upb_filedef_vtbl = {visitfiledef, freefiledef};
4370
4371upb_filedef *upb_filedef_new(const void *owner) {
4372 upb_filedef *f = upb_gmalloc(sizeof(*f));
4373
4374 if (!f) {
4375 return NULL;
4376 }
4377
4378 f->package = NULL;
4379 f->name = NULL;
4380 f->phpprefix = NULL;
4381 f->phpnamespace = NULL;
4382 f->syntax = UPB_SYNTAX_PROTO2;
4383
4384 if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl,
4385 owner)) {
4386 goto err;
4387 }
4388
4389 if (!upb_inttable_init(&f->defs, UPB_CTYPE_CONSTPTR)) {
4390 goto err;
4391 }
4392
4393 if (!upb_inttable_init(&f->deps, UPB_CTYPE_CONSTPTR)) {
4394 goto err2;
4395 }
4396
4397 return f;
4398
4399
4400err2:
4401 upb_inttable_uninit(&f->defs);
4402
4403err:
4404 upb_gfree(f);
4405 return NULL;
4406}
4407
4408const char *upb_filedef_name(const upb_filedef *f) {
4409 return f->name;
4410}
4411
4412const char *upb_filedef_package(const upb_filedef *f) {
4413 return f->package;
4414}
4415
4416const char *upb_filedef_phpprefix(const upb_filedef *f) {
4417 return f->phpprefix;
4418}
4419
4420const char *upb_filedef_phpnamespace(const upb_filedef *f) {
4421 return f->phpnamespace;
4422}
4423
4424upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
4425 return f->syntax;
4426}
4427
4428size_t upb_filedef_defcount(const upb_filedef *f) {
4429 return upb_inttable_count(&f->defs);
4430}
4431
4432size_t upb_filedef_depcount(const upb_filedef *f) {
4433 return upb_inttable_count(&f->deps);
4434}
4435
4436const upb_def *upb_filedef_def(const upb_filedef *f, size_t i) {
4437 upb_value v;
4438
4439 if (upb_inttable_lookup32(&f->defs, i, &v)) {
4440 return upb_value_getconstptr(v);
4441 } else {
4442 return NULL;
4443 }
4444}
4445
4446const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i) {
4447 upb_value v;
4448
4449 if (upb_inttable_lookup32(&f->deps, i, &v)) {
4450 return upb_value_getconstptr(v);
4451 } else {
4452 return NULL;
4453 }
4454}
4455
4456bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s) {
4457 name = upb_gstrdup(name);
4458 if (!name) {
4459 upb_upberr_setoom(s);
4460 return false;
4461 }
4462 upb_gfree((void*)f->name);
4463 f->name = name;
4464 return true;
4465}
4466
4467bool upb_filedef_setpackage(upb_filedef *f, const char *package,
4468 upb_status *s) {
4469 if (!upb_isident(package, strlen(package), true, s)) return false;
4470 package = upb_gstrdup(package);
4471 if (!package) {
4472 upb_upberr_setoom(s);
4473 return false;
4474 }
4475 upb_gfree((void*)f->package);
4476 f->package = package;
4477 return true;
4478}
4479
4480bool upb_filedef_setphpprefix(upb_filedef *f, const char *phpprefix,
4481 upb_status *s) {
4482 phpprefix = upb_gstrdup(phpprefix);
4483 if (!phpprefix) {
4484 upb_upberr_setoom(s);
4485 return false;
4486 }
4487 upb_gfree((void*)f->phpprefix);
4488 f->phpprefix = phpprefix;
4489 return true;
4490}
4491
4492bool upb_filedef_setphpnamespace(upb_filedef *f, const char *phpnamespace,
4493 upb_status *s) {
4494 phpnamespace = upb_gstrdup(phpnamespace);
4495 if (!phpnamespace) {
4496 upb_upberr_setoom(s);
4497 return false;
4498 }
4499 upb_gfree((void*)f->phpnamespace);
4500 f->phpnamespace = phpnamespace;
4501 return true;
4502}
4503
4504bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax,
4505 upb_status *s) {
4506 UPB_UNUSED(s);
4507 if (syntax != UPB_SYNTAX_PROTO2 &&
4508 syntax != UPB_SYNTAX_PROTO3) {
4509 upb_status_seterrmsg(s, "Unknown syntax value.");
4510 return false;
4511 }
4512 f->syntax = syntax;
4513
4514 {
4515 /* Set all messages in this file to match. */
4516 size_t i;
4517 for (i = 0; i < upb_filedef_defcount(f); i++) {
4518 /* Casting const away is safe since all defs in mutable filedef must
4519 * also be mutable. */
4520 upb_def *def = (upb_def*)upb_filedef_def(f, i);
4521
4522 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
4523 if (m) {
4524 m->syntax = syntax;
4525 }
4526 }
4527 }
4528
4529 return true;
4530}
4531
4532bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
4533 upb_status *s) {
4534 if (def->file) {
4535 upb_status_seterrmsg(s, "Def is already part of another filedef.");
4536 return false;
4537 }
4538
4539 if (upb_inttable_push(&f->defs, upb_value_constptr(def))) {
4540 def->file = f;
4541 upb_ref2(def, f);
4542 upb_ref2(f, def);
4543 if (ref_donor) upb_def_unref(def, ref_donor);
4544 if (def->type == UPB_DEF_MSG) {
4545 upb_downcast_msgdef_mutable(def)->syntax = f->syntax;
4546 }
4547 return true;
4548 } else {
4549 upb_upberr_setoom(s);
4550 return false;
4551 }
4552}
4553
4554bool upb_filedef_adddep(upb_filedef *f, const upb_filedef *dep) {
4555 if (upb_inttable_push(&f->deps, upb_value_constptr(dep))) {
4556 /* Regular ref instead of ref2 because files can't form cycles. */
4557 upb_filedef_ref(dep, f);
4558 return true;
4559 } else {
4560 return false;
4561 }
4562}
4563
4564void upb_symtab_free(upb_symtab *s) {
4565 upb_strtable_iter i;
4566 upb_strtable_begin(&i, &s->symtab);
4567 for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
4568 const upb_def *def = upb_value_getptr(upb_strtable_iter_value(&i));
4569 upb_def_unref(def, s);
4570 }
4571 upb_strtable_uninit(&s->symtab);
4572 upb_gfree(s);
4573}
4574
4575upb_symtab *upb_symtab_new() {
4576 upb_symtab *s = upb_gmalloc(sizeof(*s));
4577 if (!s) {
4578 return NULL;
4579 }
4580
4581 upb_strtable_init(&s->symtab, UPB_CTYPE_PTR);
4582 return s;
4583}
4584
4585const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
4586 upb_value v;
4587 upb_def *ret = upb_strtable_lookup(&s->symtab, sym, &v) ?
4588 upb_value_getptr(v) : NULL;
4589 return ret;
4590}
4591
4592const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
4593 upb_value v;
4594 upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
4595 upb_value_getptr(v) : NULL;
4596 return def ? upb_dyncast_msgdef(def) : NULL;
4597}
4598
4599const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
4600 upb_value v;
4601 upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
4602 upb_value_getptr(v) : NULL;
4603 return def ? upb_dyncast_enumdef(def) : NULL;
4604}
4605
4606/* Given a symbol and the base symbol inside which it is defined, find the
4607 * symbol's definition in t. */
4608static upb_def *upb_resolvename(const upb_strtable *t,
4609 const char *base, const char *sym) {
4610 if(strlen(sym) == 0) return NULL;
4611 if(sym[0] == '.') {
4612 /* Symbols starting with '.' are absolute, so we do a single lookup.
4613 * Slice to omit the leading '.' */
4614 upb_value v;
4615 return upb_strtable_lookup(t, sym + 1, &v) ? upb_value_getptr(v) : NULL;
4616 } else {
4617 /* Remove components from base until we find an entry or run out.
4618 * TODO: This branch is totally broken, but currently not used. */
4619 (void)base;
4620 UPB_ASSERT(false);
4621 return NULL;
4622 }
4623}
4624
4625const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
4626 const char *sym) {
4627 upb_def *ret = upb_resolvename(&s->symtab, base, sym);
4628 return ret;
4629}
4630
4631/* TODO(haberman): we need a lot more testing of error conditions. */
4632static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
4633 void *ref_donor, upb_refcounted *freeze_also,
4634 upb_status *status) {
4635 size_t i;
4636 size_t add_n;
4637 size_t freeze_n;
4638 upb_strtable_iter iter;
4639 upb_refcounted **add_objs = NULL;
4640 upb_def **add_defs = NULL;
4641 size_t add_objs_size;
4642 upb_strtable addtab;
4643
4644 if (n == 0 && !freeze_also) {
4645 return true;
4646 }
4647
4648 if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
4649 upb_status_seterrmsg(status, "out of memory");
4650 return false;
4651 }
4652
4653 /* Add new defs to our "add" set. */
4654 for (i = 0; i < n; i++) {
4655 upb_def *def = defs[i];
4656 const char *fullname;
4657 upb_fielddef *f;
4658
4659 if (upb_def_isfrozen(def)) {
4660 upb_status_seterrmsg(status, "added defs must be mutable");
4661 goto err;
4662 }
4663 UPB_ASSERT(!upb_def_isfrozen(def));
4664 fullname = upb_def_fullname(def);
4665 if (!fullname) {
4666 upb_status_seterrmsg(
4667 status, "Anonymous defs cannot be added to a symtab");
4668 goto err;
4669 }
4670
4671 f = upb_dyncast_fielddef_mutable(def);
4672
4673 if (f) {
4674 if (!upb_fielddef_containingtypename(f)) {
4675 upb_status_seterrmsg(status,
4676 "Standalone fielddefs must have a containing type "
4677 "(extendee) name set");
4678 goto err;
4679 }
4680 } else {
4681 if (upb_strtable_lookup(&addtab, fullname, NULL)) {
4682 upb_status_seterrf(status, "Conflicting defs named '%s'", fullname);
4683 goto err;
4684 }
4685 if (upb_strtable_lookup(&s->symtab, fullname, NULL)) {
4686 upb_status_seterrf(status, "Symtab already has a def named '%s'",
4687 fullname);
4688 goto err;
4689 }
4690 if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def)))
4691 goto oom_err;
4692 upb_def_donateref(def, ref_donor, s);
4693 }
4694
4695 if (upb_dyncast_fielddef_mutable(def)) {
4696 /* TODO(haberman): allow adding extensions attached to files. */
4697 upb_status_seterrf(status, "Can't add extensions to symtab.\n");
4698 goto err;
4699 }
4700 }
4701
4702 /* Now using the table, resolve symbolic references for subdefs. */
4703 upb_strtable_begin(&iter, &addtab);
4704 for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
4705 const char *base;
4706 upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
4707 upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
4708 upb_msg_field_iter j;
4709
4710 if (!m) continue;
4711 /* Type names are resolved relative to the message in which they appear. */
4712 base = upb_msgdef_fullname(m);
4713
4714 for(upb_msg_field_begin(&j, m);
4715 !upb_msg_field_done(&j);
4716 upb_msg_field_next(&j)) {
4717 upb_fielddef *f = upb_msg_iter_field(&j);
4718 const char *name = upb_fielddef_subdefname(f);
4719 if (name && !upb_fielddef_subdef(f)) {
4720 /* Try the lookup in the current set of to-be-added defs first. If not
4721 * there, try existing defs. */
4722 upb_def *subdef = upb_resolvename(&addtab, base, name);
4723 if (subdef == NULL) {
4724 subdef = upb_resolvename(&s->symtab, base, name);
4725 }
4726 if (subdef == NULL) {
4727 upb_status_seterrf(
4728 status, "couldn't resolve name '%s' in message '%s'", name, base);
4729 goto err;
4730 } else if (!upb_fielddef_setsubdef(f, subdef, status)) {
4731 goto err;
4732 }
4733 }
4734 }
4735 }
4736
4737 /* We need an array of the defs in addtab, for passing to
4738 * upb_refcounted_freeze(). */
4739 add_objs_size = upb_strtable_count(&addtab);
4740 if (freeze_also) {
4741 add_objs_size++;
4742 }
4743
4744 add_defs = upb_gmalloc(sizeof(void*) * add_objs_size);
4745 if (add_defs == NULL) goto oom_err;
4746 upb_strtable_begin(&iter, &addtab);
4747 for (add_n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
4748 add_defs[add_n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
4749 }
4750
4751 /* Validate defs. */
4752 if (!_upb_def_validate(add_defs, add_n, status)) {
4753 goto err;
4754 }
4755
4756 /* Cheat a little and give the array a new type.
4757 * This is probably undefined behavior, but this code will be deleted soon. */
4758 add_objs = (upb_refcounted**)add_defs;
4759
4760 freeze_n = add_n;
4761 if (freeze_also) {
4762 add_objs[freeze_n++] = freeze_also;
4763 }
4764
4765 if (!upb_refcounted_freeze(add_objs, freeze_n, status,
4766 UPB_MAX_MESSAGE_DEPTH * 2)) {
4767 goto err;
4768 }
4769
4770 /* This must be delayed until all errors have been detected, since error
4771 * recovery code uses this table to cleanup defs. */
4772 upb_strtable_uninit(&addtab);
4773
4774 /* TODO(haberman) we don't properly handle errors after this point (like
4775 * OOM in upb_strtable_insert() below). */
4776 for (i = 0; i < add_n; i++) {
4777 upb_def *def = (upb_def*)add_objs[i];
4778 const char *name = upb_def_fullname(def);
4779 bool success;
4780 success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
4781 UPB_ASSERT(success);
4782 }
4783 upb_gfree(add_defs);
4784 return true;
4785
4786oom_err:
4787 upb_status_seterrmsg(status, "out of memory");
4788err: {
4789 /* We need to donate the refs back. */
4790 upb_strtable_begin(&iter, &addtab);
4791 for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
4792 upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
4793 upb_def_donateref(def, s, ref_donor);
4794 }
4795 }
4796 upb_strtable_uninit(&addtab);
4797 upb_gfree(add_defs);
4798 UPB_ASSERT(!upb_ok(status));
4799 return false;
4800}
4801
4802bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
4803 void *ref_donor, upb_status *status) {
4804 return symtab_add(s, defs, n, ref_donor, NULL, status);
4805}
4806
4807bool upb_symtab_addfile(upb_symtab *s, upb_filedef *file, upb_status *status) {
4808 size_t n;
4809 size_t i;
4810 upb_def **defs;
4811 bool ret;
4812
4813 n = upb_filedef_defcount(file);
4814 if (n == 0) {
4815 return true;
4816 }
4817 defs = upb_gmalloc(sizeof(*defs) * n);
4818
4819 if (defs == NULL) {
4820 upb_status_seterrmsg(status, "Out of memory");
4821 return false;
4822 }
4823
4824 for (i = 0; i < n; i++) {
4825 defs[i] = upb_filedef_mutabledef(file, i);
4826 }
4827
4828 ret = symtab_add(s, defs, n, NULL, upb_filedef_upcast_mutable(file), status);
4829
4830 upb_gfree(defs);
4831 return ret;
4832}
4833
4834/* Iteration. */
4835
4836static void advance_to_matching(upb_symtab_iter *iter) {
4837 if (iter->type == UPB_DEF_ANY)
4838 return;
4839
4840 while (!upb_strtable_done(&iter->iter) &&
4841 iter->type != upb_symtab_iter_def(iter)->type) {
4842 upb_strtable_next(&iter->iter);
4843 }
4844}
4845
4846void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
4847 upb_deftype_t type) {
4848 upb_strtable_begin(&iter->iter, &s->symtab);
4849 iter->type = type;
4850 advance_to_matching(iter);
4851}
4852
4853void upb_symtab_next(upb_symtab_iter *iter) {
4854 upb_strtable_next(&iter->iter);
4855 advance_to_matching(iter);
4856}
4857
4858bool upb_symtab_done(const upb_symtab_iter *iter) {
4859 return upb_strtable_done(&iter->iter);
4860}
4861
4862const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
4863 return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
4864}
4865/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
4866
4867
4868#define UPB_PB_VARINT_MAX_LEN 10
4869#define CHK(x) do { if (!(x)) { return false; } } while(0)
4870
4871/* Maps descriptor type -> upb field type. */
4872static const uint8_t upb_desctype_to_fieldtype2[] = {
4873 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
4874 UPB_TYPE_DOUBLE, /* DOUBLE */
4875 UPB_TYPE_FLOAT, /* FLOAT */
4876 UPB_TYPE_INT64, /* INT64 */
4877 UPB_TYPE_UINT64, /* UINT64 */
4878 UPB_TYPE_INT32, /* INT32 */
4879 UPB_TYPE_UINT64, /* FIXED64 */
4880 UPB_TYPE_UINT32, /* FIXED32 */
4881 UPB_TYPE_BOOL, /* BOOL */
4882 UPB_TYPE_STRING, /* STRING */
4883 UPB_TYPE_MESSAGE, /* GROUP */
4884 UPB_TYPE_MESSAGE, /* MESSAGE */
4885 UPB_TYPE_BYTES, /* BYTES */
4886 UPB_TYPE_UINT32, /* UINT32 */
4887 UPB_TYPE_ENUM, /* ENUM */
4888 UPB_TYPE_INT32, /* SFIXED32 */
4889 UPB_TYPE_INT64, /* SFIXED64 */
4890 UPB_TYPE_INT32, /* SINT32 */
4891 UPB_TYPE_INT64, /* SINT64 */
4892};
4893
4894static size_t upb_encode_varint(uint64_t val, char *buf) {
4895 size_t i;
4896 if (val < 128) { buf[0] = val; return 1; }
4897 i = 0;
4898 while (val) {
4899 uint8_t byte = val & 0x7fU;
4900 val >>= 7;
4901 if (val) byte |= 0x80U;
4902 buf[i++] = byte;
4903 }
4904 return i;
4905}
4906
4907static uint32_t upb_zzencode_32(int32_t n) { return (n << 1) ^ (n >> 31); }
4908static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
4909
4910typedef struct {
4911 upb_env *env;
4912 char *buf, *ptr, *limit;
4913} upb_encstate;
4914
4915static size_t upb_roundup_pow2(size_t bytes) {
4916 size_t ret = 128;
4917 while (ret < bytes) {
4918 ret *= 2;
4919 }
4920 return ret;
4921}
4922
4923static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
4924 size_t old_size = e->limit - e->buf;
4925 size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
4926 char *new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
4927 CHK(new_buf);
4928
4929 /* We want previous data at the end, realloc() put it at the beginning. */
4930 memmove(new_buf + new_size - old_size, e->buf, old_size);
4931
4932 e->ptr = new_buf + new_size - (e->limit - e->ptr);
4933 e->limit = new_buf + new_size;
4934 e->buf = new_buf;
4935 return true;
4936}
4937
4938/* Call to ensure that at least "bytes" bytes are available for writing at
4939 * e->ptr. Returns false if the bytes could not be allocated. */
4940static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
4941 CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
4942 upb_encode_growbuffer(e, bytes));
4943
4944 e->ptr -= bytes;
4945 return true;
4946}
4947
4948/* Writes the given bytes to the buffer, handling reserve/advance. */
4949static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
4950 CHK(upb_encode_reserve(e, len));
4951 memcpy(e->ptr, data, len);
4952 return true;
4953}
4954
4955static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
4956 /* TODO(haberman): byte-swap for big endian. */
4957 return upb_put_bytes(e, &val, sizeof(uint64_t));
4958}
4959
4960static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
4961 /* TODO(haberman): byte-swap for big endian. */
4962 return upb_put_bytes(e, &val, sizeof(uint32_t));
4963}
4964
4965static bool upb_put_varint(upb_encstate *e, uint64_t val) {
4966 size_t len;
4967 char *start;
4968 CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
4969 len = upb_encode_varint(val, e->ptr);
4970 start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
4971 memmove(start, e->ptr, len);
4972 e->ptr = start;
4973 return true;
4974}
4975
4976static bool upb_put_double(upb_encstate *e, double d) {
4977 uint64_t u64;
4978 UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
4979 memcpy(&u64, &d, sizeof(uint64_t));
4980 return upb_put_fixed64(e, u64);
4981}
4982
4983static bool upb_put_float(upb_encstate *e, float d) {
4984 uint32_t u32;
4985 UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
4986 memcpy(&u32, &d, sizeof(uint32_t));
4987 return upb_put_fixed32(e, u32);
4988}
4989
4990static uint32_t upb_readcase(const char *msg, const upb_msglayout_msginit_v1 *m,
4991 int oneof_index) {
4992 uint32_t ret;
4993 memcpy(&ret, msg + m->oneofs[oneof_index].case_offset, sizeof(ret));
4994 return ret;
4995}
4996
4997static bool upb_readhasbit(const char *msg,
4998 const upb_msglayout_fieldinit_v1 *f) {
4999 UPB_ASSERT(f->hasbit != UPB_NO_HASBIT);
5000 return msg[f->hasbit / 8] & (1 << (f->hasbit % 8));
5001}
5002
5003static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
5004 return upb_put_varint(e, (field_number << 3) | wire_type);
5005}
5006
5007static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
5008 size_t size) {
5009 size_t bytes = arr->len * size;
5010 return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
5011}
5012
5013bool upb_encode_message(upb_encstate *e, const char *msg,
5014 const upb_msglayout_msginit_v1 *m,
5015 size_t *size);
5016
5017static bool upb_encode_array(upb_encstate *e, const char *field_mem,
5018 const upb_msglayout_msginit_v1 *m,
5019 const upb_msglayout_fieldinit_v1 *f) {
5020 const upb_array *arr = *(const upb_array**)field_mem;
5021
5022 if (arr == NULL || arr->len == 0) {
5023 return true;
5024 }
5025
5026 UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->descriptortype]);
5027
5028#define VARINT_CASE(ctype, encode) { \
5029 ctype *start = arr->data; \
5030 ctype *ptr = start + arr->len; \
5031 size_t pre_len = e->limit - e->ptr; \
5032 do { \
5033 ptr--; \
5034 CHK(upb_put_varint(e, encode)); \
5035 } while (ptr != start); \
5036 CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
5037} \
5038break; \
5039do { ; } while(0)
5040
5041 switch (f->descriptortype) {
5042 case UPB_DESCRIPTOR_TYPE_DOUBLE:
5043 CHK(upb_put_fixedarray(e, arr, sizeof(double)));
5044 break;
5045 case UPB_DESCRIPTOR_TYPE_FLOAT:
5046 CHK(upb_put_fixedarray(e, arr, sizeof(float)));
5047 break;
5048 case UPB_DESCRIPTOR_TYPE_SFIXED64:
5049 case UPB_DESCRIPTOR_TYPE_FIXED64:
5050 CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
5051 break;
5052 case UPB_DESCRIPTOR_TYPE_FIXED32:
5053 case UPB_DESCRIPTOR_TYPE_SFIXED32:
5054 CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
5055 break;
5056 case UPB_DESCRIPTOR_TYPE_INT64:
5057 case UPB_DESCRIPTOR_TYPE_UINT64:
5058 VARINT_CASE(uint64_t, *ptr);
5059 case UPB_DESCRIPTOR_TYPE_UINT32:
5060 VARINT_CASE(uint32_t, *ptr);
5061 case UPB_DESCRIPTOR_TYPE_INT32:
5062 case UPB_DESCRIPTOR_TYPE_ENUM:
5063 VARINT_CASE(int32_t, (int64_t)*ptr);
5064 case UPB_DESCRIPTOR_TYPE_BOOL:
5065 VARINT_CASE(bool, *ptr);
5066 case UPB_DESCRIPTOR_TYPE_SINT32:
5067 VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
5068 case UPB_DESCRIPTOR_TYPE_SINT64:
5069 VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
5070 case UPB_DESCRIPTOR_TYPE_STRING:
5071 case UPB_DESCRIPTOR_TYPE_BYTES: {
5072 upb_stringview *start = arr->data;
5073 upb_stringview *ptr = start + arr->len;
5074 do {
5075 ptr--;
5076 CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
5077 upb_put_varint(e, ptr->size) &&
5078 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
5079 } while (ptr != start);
5080 return true;
5081 }
5082 case UPB_DESCRIPTOR_TYPE_GROUP: {
5083 void **start = arr->data;
5084 void **ptr = start + arr->len;
5085 const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
5086 do {
5087 size_t size;
5088 ptr--;
5089 CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
5090 upb_encode_message(e, *ptr, subm, &size) &&
5091 upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
5092 } while (ptr != start);
5093 return true;
5094 }
5095 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
5096 void **start = arr->data;
5097 void **ptr = start + arr->len;
5098 const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
5099 do {
5100 size_t size;
5101 ptr--;
5102 CHK(upb_encode_message(e, *ptr, subm, &size) &&
5103 upb_put_varint(e, size) &&
5104 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
5105 } while (ptr != start);
5106 return true;
5107 }
5108 }
5109#undef VARINT_CASE
5110
5111 /* We encode all primitive arrays as packed, regardless of what was specified
5112 * in the .proto file. Could special case 1-sized arrays. */
5113 CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
5114 return true;
5115}
5116
5117static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
5118 const upb_msglayout_msginit_v1 *m,
5119 const upb_msglayout_fieldinit_v1 *f,
5120 bool is_proto3) {
5121 bool skip_zero_value = is_proto3 && f->oneof_index == UPB_NOT_IN_ONEOF;
5122
5123#define CASE(ctype, type, wire_type, encodeval) do { \
5124 ctype val = *(ctype*)field_mem; \
5125 if (skip_zero_value && val == 0) { \
5126 return true; \
5127 } \
5128 return upb_put_ ## type(e, encodeval) && \
5129 upb_put_tag(e, f->number, wire_type); \
5130} while(0)
5131
5132 switch (f->descriptortype) {
5133 case UPB_DESCRIPTOR_TYPE_DOUBLE:
5134 CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
5135 case UPB_DESCRIPTOR_TYPE_FLOAT:
5136 CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
5137 case UPB_DESCRIPTOR_TYPE_INT64:
5138 case UPB_DESCRIPTOR_TYPE_UINT64:
5139 CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
5140 case UPB_DESCRIPTOR_TYPE_UINT32:
5141 CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
5142 case UPB_DESCRIPTOR_TYPE_INT32:
5143 case UPB_DESCRIPTOR_TYPE_ENUM:
5144 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val);
5145 case UPB_DESCRIPTOR_TYPE_SFIXED64:
5146 case UPB_DESCRIPTOR_TYPE_FIXED64:
5147 CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
5148 case UPB_DESCRIPTOR_TYPE_FIXED32:
5149 case UPB_DESCRIPTOR_TYPE_SFIXED32:
5150 CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
5151 case UPB_DESCRIPTOR_TYPE_BOOL:
5152 CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
5153 case UPB_DESCRIPTOR_TYPE_SINT32:
5154 CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
5155 case UPB_DESCRIPTOR_TYPE_SINT64:
5156 CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
5157 case UPB_DESCRIPTOR_TYPE_STRING:
5158 case UPB_DESCRIPTOR_TYPE_BYTES: {
5159 upb_stringview view = *(upb_stringview*)field_mem;
5160 if (skip_zero_value && view.size == 0) {
5161 return true;
5162 }
5163 return upb_put_bytes(e, view.data, view.size) &&
5164 upb_put_varint(e, view.size) &&
5165 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
5166 }
5167 case UPB_DESCRIPTOR_TYPE_GROUP: {
5168 size_t size;
5169 void *submsg = *(void**)field_mem;
5170 const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
5171 if (skip_zero_value && submsg == NULL) {
5172 return true;
5173 }
5174 return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
5175 upb_encode_message(e, submsg, subm, &size) &&
5176 upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
5177 }
5178 case UPB_DESCRIPTOR_TYPE_MESSAGE: {
5179 size_t size;
5180 void *submsg = *(void**)field_mem;
5181 const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
5182 if (skip_zero_value && submsg == NULL) {
5183 return true;
5184 }
5185 return upb_encode_message(e, submsg, subm, &size) &&
5186 upb_put_varint(e, size) &&
5187 upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
5188 }
5189 }
5190#undef CASE
5191 UPB_UNREACHABLE();
5192}
5193
5194bool upb_encode_hasscalarfield(const char *msg,
5195 const upb_msglayout_msginit_v1 *m,
5196 const upb_msglayout_fieldinit_v1 *f) {
5197 if (f->oneof_index != UPB_NOT_IN_ONEOF) {
5198 return upb_readcase(msg, m, f->oneof_index) == f->number;
5199 } else if (m->is_proto2) {
5200 return upb_readhasbit(msg, f);
5201 } else {
5202 /* For proto3, we'll test for the field being empty later. */
5203 return true;
5204 }
5205}
5206
5207bool upb_encode_message(upb_encstate* e, const char *msg,
5208 const upb_msglayout_msginit_v1 *m,
5209 size_t *size) {
5210 int i;
5211 size_t pre_len = e->limit - e->ptr;
5212
5213 if (msg == NULL) {
5214 return true;
5215 }
5216
5217 for (i = m->field_count - 1; i >= 0; i--) {
5218 const upb_msglayout_fieldinit_v1 *f = &m->fields[i];
5219
5220 if (f->label == UPB_LABEL_REPEATED) {
5221 CHK(upb_encode_array(e, msg + f->offset, m, f));
5222 } else {
5223 if (upb_encode_hasscalarfield(msg, m, f)) {
5224 if (f->oneof_index == UPB_NOT_IN_ONEOF) {
5225 CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, !m->is_proto2));
5226 } else {
5227 const upb_msglayout_oneofinit_v1 *o = &m->oneofs[f->oneof_index];
5228 CHK(upb_encode_scalarfield(e, msg + o->data_offset,
5229 m, f, !m->is_proto2));
5230 }
5231 }
5232 }
5233 }
5234
5235 *size = (e->limit - e->ptr) - pre_len;
5236 return true;
5237}
5238
5239char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *m,
5240 upb_env *env, size_t *size) {
5241 upb_encstate e;
5242 e.env = env;
5243 e.buf = NULL;
5244 e.limit = NULL;
5245 e.ptr = NULL;
5246
5247 if (!upb_encode_message(&e, msg, m, size)) {
5248 *size = 0;
5249 return NULL;
5250 }
5251
5252 *size = e.limit - e.ptr;
5253
5254 if (*size == 0) {
5255 static char ch;
5256 return &ch;
5257 } else {
5258 UPB_ASSERT(e.ptr);
5259 return e.ptr;
5260 }
5261}
5262
5263#undef CHK
5264/*
5265** TODO(haberman): it's unclear whether a lot of the consistency checks should
5266** UPB_ASSERT() or return false.
5267*/
5268
5269
5270#include <string.h>
5271
5272
5273static void *upb_calloc(size_t size) {
5274 void *mem = upb_gmalloc(size);
5275 if (mem) {
5276 memset(mem, 0, size);
5277 }
5278 return mem;
5279}
5280
5281/* Defined for the sole purpose of having a unique pointer value for
5282 * UPB_NO_CLOSURE. */
5283char _upb_noclosure;
5284
5285static void freehandlers(upb_refcounted *r) {
5286 upb_handlers *h = (upb_handlers*)r;
5287
5288 upb_inttable_iter i;
5289 upb_inttable_begin(&i, &h->cleanup_);
5290 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
5291 void *val = (void*)upb_inttable_iter_key(&i);
5292 upb_value func_val = upb_inttable_iter_value(&i);
5293 upb_handlerfree *func = upb_value_getfptr(func_val);
5294 func(val);
5295 }
5296
5297 upb_inttable_uninit(&h->cleanup_);
5298 upb_msgdef_unref(h->msg, h);
5299 upb_gfree(h->sub);
5300 upb_gfree(h);
5301}
5302
5303static void visithandlers(const upb_refcounted *r, upb_refcounted_visit *visit,
5304 void *closure) {
5305 const upb_handlers *h = (const upb_handlers*)r;
5306 upb_msg_field_iter i;
5307 for(upb_msg_field_begin(&i, h->msg);
5308 !upb_msg_field_done(&i);
5309 upb_msg_field_next(&i)) {
5310 upb_fielddef *f = upb_msg_iter_field(&i);
5311 const upb_handlers *sub;
5312 if (!upb_fielddef_issubmsg(f)) continue;
5313 sub = upb_handlers_getsubhandlers(h, f);
5314 if (sub) visit(r, upb_handlers_upcast(sub), closure);
5315 }
5316}
5317
5318static const struct upb_refcounted_vtbl vtbl = {visithandlers, freehandlers};
5319
5320typedef struct {
5321 upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */
5322 upb_handlers_callback *callback;
5323 const void *closure;
5324} dfs_state;
5325
5326/* TODO(haberman): discard upb_handlers* objects that do not actually have any
5327 * handlers set and cannot reach any upb_handlers* object that does. This is
5328 * slightly tricky to do correctly. */
5329static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
5330 dfs_state *s) {
5331 upb_msg_field_iter i;
5332 upb_handlers *h = upb_handlers_new(m, owner);
5333 if (!h) return NULL;
5334 if (!upb_inttable_insertptr(&s->tab, m, upb_value_ptr(h))) goto oom;
5335
5336 s->callback(s->closure, h);
5337
5338 /* For each submessage field, get or create a handlers object and set it as
5339 * the subhandlers. */
5340 for(upb_msg_field_begin(&i, m);
5341 !upb_msg_field_done(&i);
5342 upb_msg_field_next(&i)) {
5343 upb_fielddef *f = upb_msg_iter_field(&i);
5344 const upb_msgdef *subdef;
5345 upb_value subm_ent;
5346
5347 if (!upb_fielddef_issubmsg(f)) continue;
5348
5349 subdef = upb_downcast_msgdef(upb_fielddef_subdef(f));
5350 if (upb_inttable_lookupptr(&s->tab, subdef, &subm_ent)) {
5351 upb_handlers_setsubhandlers(h, f, upb_value_getptr(subm_ent));
5352 } else {
5353 upb_handlers *sub_mh = newformsg(subdef, &sub_mh, s);
5354 if (!sub_mh) goto oom;
5355 upb_handlers_setsubhandlers(h, f, sub_mh);
5356 upb_handlers_unref(sub_mh, &sub_mh);
5357 }
5358 }
5359 return h;
5360
5361oom:
5362 upb_handlers_unref(h, owner);
5363 return NULL;
5364}
5365
5366/* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
5367 * subhandlers for this submessage field. */
5368#define SUBH(h, selector) (h->sub[selector])
5369
5370/* The selector for a submessage field is the field index. */
5371#define SUBH_F(h, f) SUBH(h, f->index_)
5372
5373static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
5374 upb_handlertype_t type) {
5375 upb_selector_t sel;
5376 UPB_ASSERT(!upb_handlers_isfrozen(h));
5377 if (upb_handlers_msgdef(h) != upb_fielddef_containingtype(f)) {
5378 upb_status_seterrf(
5379 &h->status_, "type mismatch: field %s does not belong to message %s",
5380 upb_fielddef_name(f), upb_msgdef_fullname(upb_handlers_msgdef(h)));
5381 return -1;
5382 }
5383 if (!upb_handlers_getselector(f, type, &sel)) {
5384 upb_status_seterrf(
5385 &h->status_,
5386 "type mismatch: cannot register handler type %d for field %s",
5387 type, upb_fielddef_name(f));
5388 return -1;
5389 }
5390 return sel;
5391}
5392
5393static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f,
5394 upb_handlertype_t type) {
5395 int32_t sel = trygetsel(h, f, type);
5396 UPB_ASSERT(sel >= 0);
5397 return sel;
5398}
5399
5400static const void **returntype(upb_handlers *h, const upb_fielddef *f,
5401 upb_handlertype_t type) {
5402 return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type_;
5403}
5404
5405static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
5406 upb_handlertype_t type, upb_func *func,
5407 upb_handlerattr *attr) {
5408 upb_handlerattr set_attr = UPB_HANDLERATTR_INITIALIZER;
5409 const void *closure_type;
5410 const void **context_closure_type;
5411
5412 UPB_ASSERT(!upb_handlers_isfrozen(h));
5413
5414 if (sel < 0) {
5415 upb_status_seterrmsg(&h->status_,
5416 "incorrect handler type for this field.");
5417 return false;
5418 }
5419
5420 if (h->table[sel].func) {
5421 upb_status_seterrmsg(&h->status_,
5422 "cannot change handler once it has been set.");
5423 return false;
5424 }
5425
5426 if (attr) {
5427 set_attr = *attr;
5428 }
5429
5430 /* Check that the given closure type matches the closure type that has been
5431 * established for this context (if any). */
5432 closure_type = upb_handlerattr_closuretype(&set_attr);
5433
5434 if (type == UPB_HANDLER_STRING) {
5435 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
5436 } else if (f && upb_fielddef_isseq(f) &&
5437 type != UPB_HANDLER_STARTSEQ &&
5438 type != UPB_HANDLER_ENDSEQ) {
5439 context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
5440 } else {
5441 context_closure_type = &h->top_closure_type;
5442 }
5443
5444 if (closure_type && *context_closure_type &&
5445 closure_type != *context_closure_type) {
5446 /* TODO(haberman): better message for debugging. */
5447 if (f) {
5448 upb_status_seterrf(&h->status_,
5449 "closure type does not match for field %s",
5450 upb_fielddef_name(f));
5451 } else {
5452 upb_status_seterrmsg(
5453 &h->status_, "closure type does not match for message-level handler");
5454 }
5455 return false;
5456 }
5457
5458 if (closure_type)
5459 *context_closure_type = closure_type;
5460
5461 /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
5462 * matches any pre-existing expectations about what type is expected. */
5463 if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) {
5464 const void *return_type = upb_handlerattr_returnclosuretype(&set_attr);
5465 const void *table_return_type =
5466 upb_handlerattr_returnclosuretype(&h->table[sel].attr);
5467 if (return_type && table_return_type && return_type != table_return_type) {
5468 upb_status_seterrmsg(&h->status_, "closure return type does not match");
5469 return false;
5470 }
5471
5472 if (table_return_type && !return_type)
5473 upb_handlerattr_setreturnclosuretype(&set_attr, table_return_type);
5474 }
5475
5476 h->table[sel].func = (upb_func*)func;
5477 h->table[sel].attr = set_attr;
5478 return true;
5479}
5480
5481/* Returns the effective closure type for this handler (which will propagate
5482 * from outer frames if this frame has no START* handler). Not implemented for
5483 * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is
5484 * the effective closure type is unspecified (either no handler was registered
5485 * to specify it or the handler that was registered did not specify the closure
5486 * type). */
5487const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f,
5488 upb_handlertype_t type) {
5489 const void *ret;
5490 upb_selector_t sel;
5491
5492 UPB_ASSERT(type != UPB_HANDLER_STRING);
5493 ret = h->top_closure_type;
5494
5495 if (upb_fielddef_isseq(f) &&
5496 type != UPB_HANDLER_STARTSEQ &&
5497 type != UPB_HANDLER_ENDSEQ &&
5498 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
5499 ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
5500 }
5501
5502 if (type == UPB_HANDLER_STRING &&
5503 h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
5504 ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
5505 }
5506
5507 /* The effective type of the submessage; not used yet.
5508 * if (type == SUBMESSAGE &&
5509 * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
5510 * ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
5511 * } */
5512
5513 return ret;
5514}
5515
5516/* Checks whether the START* handler specified by f & type is missing even
5517 * though it is required to convert the established type of an outer frame
5518 * ("closure_type") into the established type of an inner frame (represented in
5519 * the return closure type of this handler's attr. */
5520bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type,
5521 upb_status *status) {
5522 const void *closure_type;
5523 const upb_handlerattr *attr;
5524 const void *return_closure_type;
5525
5526 upb_selector_t sel = handlers_getsel(h, f, type);
5527 if (h->table[sel].func) return true;
5528 closure_type = effective_closure_type(h, f, type);
5529 attr = &h->table[sel].attr;
5530 return_closure_type = upb_handlerattr_returnclosuretype(attr);
5531 if (closure_type && return_closure_type &&
5532 closure_type != return_closure_type) {
5533 upb_status_seterrf(status,
5534 "expected start handler to return sub type for field %f",
5535 upb_fielddef_name(f));
5536 return false;
5537 }
5538 return true;
5539}
5540
5541/* Public interface ***********************************************************/
5542
5543upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
5544 int extra;
5545 upb_handlers *h;
5546
5547 UPB_ASSERT(upb_msgdef_isfrozen(md));
5548
5549 extra = sizeof(upb_handlers_tabent) * (md->selector_count - 1);
5550 h = upb_calloc(sizeof(*h) + extra);
5551 if (!h) return NULL;
5552
5553 h->msg = md;
5554 upb_msgdef_ref(h->msg, h);
5555 upb_status_clear(&h->status_);
5556
5557 if (md->submsg_field_count > 0) {
5558 h->sub = upb_calloc(md->submsg_field_count * sizeof(*h->sub));
5559 if (!h->sub) goto oom;
5560 } else {
5561 h->sub = 0;
5562 }
5563
5564 if (!upb_refcounted_init(upb_handlers_upcast_mutable(h), &vtbl, owner))
5565 goto oom;
5566 if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
5567
5568 /* calloc() above initialized all handlers to NULL. */
5569 return h;
5570
5571oom:
5572 freehandlers(upb_handlers_upcast_mutable(h));
5573 return NULL;
5574}
5575
5576const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
5577 const void *owner,
5578 upb_handlers_callback *callback,
5579 const void *closure) {
5580 dfs_state state;
5581 upb_handlers *ret;
5582 bool ok;
5583 upb_refcounted *r;
5584
5585 state.callback = callback;
5586 state.closure = closure;
5587 if (!upb_inttable_init(&state.tab, UPB_CTYPE_PTR)) return NULL;
5588
5589 ret = newformsg(m, owner, &state);
5590
5591 upb_inttable_uninit(&state.tab);
5592 if (!ret) return NULL;
5593
5594 r = upb_handlers_upcast_mutable(ret);
5595 ok = upb_refcounted_freeze(&r, 1, NULL, UPB_MAX_HANDLER_DEPTH);
5596 UPB_ASSERT(ok);
5597
5598 return ret;
5599}
5600
5601const upb_status *upb_handlers_status(upb_handlers *h) {
5602 UPB_ASSERT(!upb_handlers_isfrozen(h));
5603 return &h->status_;
5604}
5605
5606void upb_handlers_clearerr(upb_handlers *h) {
5607 UPB_ASSERT(!upb_handlers_isfrozen(h));
5608 upb_status_clear(&h->status_);
5609}
5610
5611#define SETTER(name, handlerctype, handlertype) \
5612 bool upb_handlers_set ## name(upb_handlers *h, const upb_fielddef *f, \
5613 handlerctype func, upb_handlerattr *attr) { \
5614 int32_t sel = trygetsel(h, f, handlertype); \
5615 return doset(h, sel, f, handlertype, (upb_func*)func, attr); \
5616 }
5617
5618SETTER(int32, upb_int32_handlerfunc*, UPB_HANDLER_INT32)
5619SETTER(int64, upb_int64_handlerfunc*, UPB_HANDLER_INT64)
5620SETTER(uint32, upb_uint32_handlerfunc*, UPB_HANDLER_UINT32)
5621SETTER(uint64, upb_uint64_handlerfunc*, UPB_HANDLER_UINT64)
5622SETTER(float, upb_float_handlerfunc*, UPB_HANDLER_FLOAT)
5623SETTER(double, upb_double_handlerfunc*, UPB_HANDLER_DOUBLE)
5624SETTER(bool, upb_bool_handlerfunc*, UPB_HANDLER_BOOL)
5625SETTER(startstr, upb_startstr_handlerfunc*, UPB_HANDLER_STARTSTR)
5626SETTER(string, upb_string_handlerfunc*, UPB_HANDLER_STRING)
5627SETTER(endstr, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSTR)
5628SETTER(startseq, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSEQ)
5629SETTER(startsubmsg, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSUBMSG)
5630SETTER(endsubmsg, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSUBMSG)
5631SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
5632
5633#undef SETTER
5634
5635bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
5636 upb_handlerattr *attr) {
5637 return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
5638 (upb_func *)func, attr);
5639}
5640
5641bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
5642 upb_handlerattr *attr) {
5643 return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
5644 (upb_func *)func, attr);
5645}
5646
5647bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
5648 upb_handlerattr *attr) {
5649 UPB_ASSERT(!upb_handlers_isfrozen(h));
5650 return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
5651 (upb_func *)func, attr);
5652}
5653
5654bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
5655 const upb_handlers *sub) {
5656 UPB_ASSERT(sub);
5657 UPB_ASSERT(!upb_handlers_isfrozen(h));
5658 UPB_ASSERT(upb_fielddef_issubmsg(f));
5659 if (SUBH_F(h, f)) return false; /* Can't reset. */
5660 if (upb_msgdef_upcast(upb_handlers_msgdef(sub)) != upb_fielddef_subdef(f)) {
5661 return false;
5662 }
5663 SUBH_F(h, f) = sub;
5664 upb_ref2(sub, h);
5665 return true;
5666}
5667
5668const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
5669 const upb_fielddef *f) {
5670 UPB_ASSERT(upb_fielddef_issubmsg(f));
5671 return SUBH_F(h, f);
5672}
5673
5674bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
5675 upb_handlerattr *attr) {
5676 if (!upb_handlers_gethandler(h, sel))
5677 return false;
5678 *attr = h->table[sel].attr;
5679 return true;
5680}
5681
5682const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
5683 upb_selector_t sel) {
5684 /* STARTSUBMSG selector in sel is the field's selector base. */
5685 return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
5686}
5687
5688const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
5689
5690bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
5691 bool ok;
5692 if (upb_inttable_lookupptr(&h->cleanup_, p, NULL)) {
5693 return false;
5694 }
5695 ok = upb_inttable_insertptr(&h->cleanup_, p, upb_value_fptr(func));
5696 UPB_ASSERT(ok);
5697 return true;
5698}
5699
5700
5701/* "Static" methods ***********************************************************/
5702
5703bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s) {
5704 /* TODO: verify we have a transitive closure. */
5705 int i;
5706 for (i = 0; i < n; i++) {
5707 upb_msg_field_iter j;
5708 upb_handlers *h = handlers[i];
5709
5710 if (!upb_ok(&h->status_)) {
5711 upb_status_seterrf(s, "handlers for message %s had error status: %s",
5712 upb_msgdef_fullname(upb_handlers_msgdef(h)),
5713 upb_status_errmsg(&h->status_));
5714 return false;
5715 }
5716
5717 /* Check that there are no closure mismatches due to missing Start* handlers
5718 * or subhandlers with different type-level types. */
5719 for(upb_msg_field_begin(&j, h->msg);
5720 !upb_msg_field_done(&j);
5721 upb_msg_field_next(&j)) {
5722
5723 const upb_fielddef *f = upb_msg_iter_field(&j);
5724 if (upb_fielddef_isseq(f)) {
5725 if (!checkstart(h, f, UPB_HANDLER_STARTSEQ, s))
5726 return false;
5727 }
5728
5729 if (upb_fielddef_isstring(f)) {
5730 if (!checkstart(h, f, UPB_HANDLER_STARTSTR, s))
5731 return false;
5732 }
5733
5734 if (upb_fielddef_issubmsg(f)) {
5735 bool hashandler = false;
5736 if (upb_handlers_gethandler(
5737 h, handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)) ||
5738 upb_handlers_gethandler(
5739 h, handlers_getsel(h, f, UPB_HANDLER_ENDSUBMSG))) {
5740 hashandler = true;
5741 }
5742
5743 if (upb_fielddef_isseq(f) &&
5744 (upb_handlers_gethandler(
5745 h, handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)) ||
5746 upb_handlers_gethandler(
5747 h, handlers_getsel(h, f, UPB_HANDLER_ENDSEQ)))) {
5748 hashandler = true;
5749 }
5750
5751 if (hashandler && !upb_handlers_getsubhandlers(h, f)) {
5752 /* For now we add an empty subhandlers in this case. It makes the
5753 * decoder code generator simpler, because it only has to handle two
5754 * cases (submessage has handlers or not) as opposed to three
5755 * (submessage has handlers in enclosing message but no subhandlers).
5756 *
5757 * This makes parsing less efficient in the case that we want to
5758 * notice a submessage but skip its contents (like if we're testing
5759 * for submessage presence or counting the number of repeated
5760 * submessages). In this case we will end up parsing the submessage
5761 * field by field and throwing away the results for each, instead of
5762 * skipping the whole delimited thing at once. If this is an issue we
5763 * can revisit it, but do remember that this only arises when you have
5764 * handlers (startseq/startsubmsg/endsubmsg/endseq) set for the
5765 * submessage but no subhandlers. The uses cases for this are
5766 * limited. */
5767 upb_handlers *sub = upb_handlers_new(upb_fielddef_msgsubdef(f), &sub);
5768 upb_handlers_setsubhandlers(h, f, sub);
5769 upb_handlers_unref(sub, &sub);
5770 }
5771
5772 /* TODO(haberman): check type of submessage.
5773 * This is slightly tricky; also consider whether we should check that
5774 * they match at setsubhandlers time. */
5775 }
5776 }
5777 }
5778
5779 if (!upb_refcounted_freeze((upb_refcounted*const*)handlers, n, s,
5780 UPB_MAX_HANDLER_DEPTH)) {
5781 return false;
5782 }
5783
5784 return true;
5785}
5786
5787upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) {
5788 switch (upb_fielddef_type(f)) {
5789 case UPB_TYPE_INT32:
5790 case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
5791 case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
5792 case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
5793 case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
5794 case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
5795 case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
5796 case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
5797 default: UPB_ASSERT(false); return -1; /* Invalid input. */
5798 }
5799}
5800
5801bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
5802 upb_selector_t *s) {
5803 switch (type) {
5804 case UPB_HANDLER_INT32:
5805 case UPB_HANDLER_INT64:
5806 case UPB_HANDLER_UINT32:
5807 case UPB_HANDLER_UINT64:
5808 case UPB_HANDLER_FLOAT:
5809 case UPB_HANDLER_DOUBLE:
5810 case UPB_HANDLER_BOOL:
5811 if (!upb_fielddef_isprimitive(f) ||
5812 upb_handlers_getprimitivehandlertype(f) != type)
5813 return false;
5814 *s = f->selector_base;
5815 break;
5816 case UPB_HANDLER_STRING:
5817 if (upb_fielddef_isstring(f)) {
5818 *s = f->selector_base;
5819 } else if (upb_fielddef_lazy(f)) {
5820 *s = f->selector_base + 3;
5821 } else {
5822 return false;
5823 }
5824 break;
5825 case UPB_HANDLER_STARTSTR:
5826 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
5827 *s = f->selector_base + 1;
5828 } else {
5829 return false;
5830 }
5831 break;
5832 case UPB_HANDLER_ENDSTR:
5833 if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
5834 *s = f->selector_base + 2;
5835 } else {
5836 return false;
5837 }
5838 break;
5839 case UPB_HANDLER_STARTSEQ:
5840 if (!upb_fielddef_isseq(f)) return false;
5841 *s = f->selector_base - 2;
5842 break;
5843 case UPB_HANDLER_ENDSEQ:
5844 if (!upb_fielddef_isseq(f)) return false;
5845 *s = f->selector_base - 1;
5846 break;
5847 case UPB_HANDLER_STARTSUBMSG:
5848 if (!upb_fielddef_issubmsg(f)) return false;
5849 /* Selectors for STARTSUBMSG are at the beginning of the table so that the
5850 * selector can also be used as an index into the "sub" array of
5851 * subhandlers. The indexes for the two into these two tables are the
5852 * same, except that in the handler table the static selectors come first. */
5853 *s = f->index_ + UPB_STATIC_SELECTOR_COUNT;
5854 break;
5855 case UPB_HANDLER_ENDSUBMSG:
5856 if (!upb_fielddef_issubmsg(f)) return false;
5857 *s = f->selector_base;
5858 break;
5859 }
5860 UPB_ASSERT((size_t)*s < upb_fielddef_containingtype(f)->selector_count);
5861 return true;
5862}
5863
5864uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
5865 return upb_fielddef_isseq(f) ? 2 : 0;
5866}
5867
5868uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
5869 uint32_t ret = 1;
5870 if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
5871 if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
5872 if (upb_fielddef_issubmsg(f)) {
5873 /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
5874 ret += 0;
5875 if (upb_fielddef_lazy(f)) {
5876 /* STARTSTR/ENDSTR/STRING (for lazy) */
5877 ret += 3;
5878 }
5879 }
5880 return ret;
5881}
5882
5883
5884/* upb_handlerattr ************************************************************/
5885
5886void upb_handlerattr_init(upb_handlerattr *attr) {
5887 upb_handlerattr from = UPB_HANDLERATTR_INITIALIZER;
5888 memcpy(attr, &from, sizeof(*attr));
5889}
5890
5891void upb_handlerattr_uninit(upb_handlerattr *attr) {
5892 UPB_UNUSED(attr);
5893}
5894
5895bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd) {
5896 attr->handler_data_ = hd;
5897 return true;
5898}
5899
5900bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type) {
5901 attr->closure_type_ = type;
5902 return true;
5903}
5904
5905const void *upb_handlerattr_closuretype(const upb_handlerattr *attr) {
5906 return attr->closure_type_;
5907}
5908
5909bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
5910 const void *type) {
5911 attr->return_closure_type_ = type;
5912 return true;
5913}
5914
5915const void *upb_handlerattr_returnclosuretype(const upb_handlerattr *attr) {
5916 return attr->return_closure_type_;
5917}
5918
5919bool upb_handlerattr_setalwaysok(upb_handlerattr *attr, bool alwaysok) {
5920 attr->alwaysok_ = alwaysok;
5921 return true;
5922}
5923
5924bool upb_handlerattr_alwaysok(const upb_handlerattr *attr) {
5925 return attr->alwaysok_;
5926}
5927
5928/* upb_bufhandle **************************************************************/
5929
5930size_t upb_bufhandle_objofs(const upb_bufhandle *h) {
5931 return h->objofs_;
5932}
5933
5934/* upb_byteshandler ***********************************************************/
5935
5936void upb_byteshandler_init(upb_byteshandler* h) {
5937 memset(h, 0, sizeof(*h));
5938}
5939
5940/* For when we support handlerfree callbacks. */
5941void upb_byteshandler_uninit(upb_byteshandler* h) {
5942 UPB_UNUSED(h);
5943}
5944
5945bool upb_byteshandler_setstartstr(upb_byteshandler *h,
5946 upb_startstr_handlerfunc *func, void *d) {
5947 h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
5948 h->table[UPB_STARTSTR_SELECTOR].attr.handler_data_ = d;
5949 return true;
5950}
5951
5952bool upb_byteshandler_setstring(upb_byteshandler *h,
5953 upb_string_handlerfunc *func, void *d) {
5954 h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
5955 h->table[UPB_STRING_SELECTOR].attr.handler_data_ = d;
5956 return true;
5957}
5958
5959bool upb_byteshandler_setendstr(upb_byteshandler *h,
5960 upb_endfield_handlerfunc *func, void *d) {
5961 h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
5962 h->table[UPB_ENDSTR_SELECTOR].attr.handler_data_ = d;
5963 return true;
5964}
5965
5966
5967static bool is_power_of_two(size_t val) {
5968 return (val & (val - 1)) == 0;
5969}
5970
5971/* Align up to the given power of 2. */
5972static size_t align_up(size_t val, size_t align) {
5973 UPB_ASSERT(is_power_of_two(align));
5974 return (val + align - 1) & ~(align - 1);
5975}
5976
5977static size_t div_round_up(size_t n, size_t d) {
5978 return (n + d - 1) / d;
5979}
5980
5981bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
5982 return type == UPB_TYPE_BOOL || type == UPB_TYPE_INT32 ||
5983 type == UPB_TYPE_UINT32 || type == UPB_TYPE_INT64 ||
5984 type == UPB_TYPE_UINT64 || type == UPB_TYPE_STRING;
5985}
5986
5987void *upb_array_pack(const upb_array *arr, void *p, size_t *ofs, size_t size);
5988void *upb_map_pack(const upb_map *map, void *p, size_t *ofs, size_t size);
5989
5990#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
5991#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
5992#define ENCODE_MAX_NESTING 64
5993#define CHECK_TRUE(x) if (!(x)) { return false; }
5994
5995/** upb_msgval ****************************************************************/
5996
5997#define upb_alignof(t) offsetof(struct { char c; t x; }, x)
5998
5999/* These functions will generate real memcpy() calls on ARM sadly, because
6000 * the compiler assumes they might not be aligned. */
6001
6002static upb_msgval upb_msgval_read(const void *p, size_t ofs,
6003 uint8_t size) {
6004 upb_msgval val;
6005 p = (char*)p + ofs;
6006 memcpy(&val, p, size);
6007 return val;
6008}
6009
6010static void upb_msgval_write(void *p, size_t ofs, upb_msgval val,
6011 uint8_t size) {
6012 p = (char*)p + ofs;
6013 memcpy(p, &val, size);
6014}
6015
6016static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
6017 switch (type) {
6018 case UPB_TYPE_DOUBLE:
6019 case UPB_TYPE_INT64:
6020 case UPB_TYPE_UINT64:
6021 return 8;
6022 case UPB_TYPE_ENUM:
6023 case UPB_TYPE_INT32:
6024 case UPB_TYPE_UINT32:
6025 case UPB_TYPE_FLOAT:
6026 return 4;
6027 case UPB_TYPE_BOOL:
6028 return 1;
6029 case UPB_TYPE_MESSAGE:
6030 return sizeof(void*);
6031 case UPB_TYPE_BYTES:
6032 case UPB_TYPE_STRING:
6033 return sizeof(upb_stringview);
6034 }
6035 UPB_UNREACHABLE();
6036}
6037
6038static uint8_t upb_msg_fieldsize(const upb_msglayout_fieldinit_v1 *field) {
6039 if (field->label == UPB_LABEL_REPEATED) {
6040 return sizeof(void*);
6041 } else {
6042 return upb_msgval_sizeof(upb_desctype_to_fieldtype[field->descriptortype]);
6043 }
6044}
6045
6046static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
6047 if (upb_fielddef_isseq(f)) {
6048 return sizeof(void*);
6049 } else {
6050 return upb_msgval_sizeof(upb_fielddef_type(f));
6051 }
6052}
6053
6054/* TODO(haberman): this is broken right now because upb_msgval can contain
6055 * a char* / size_t pair, which is too big for a upb_value. To fix this
6056 * we'll probably need to dynamically allocate a upb_msgval and store a
6057 * pointer to that in the tables for extensions/maps. */
6058static upb_value upb_toval(upb_msgval val) {
6059 upb_value ret;
6060 UPB_UNUSED(val);
6061 memset(&ret, 0, sizeof(upb_value)); /* XXX */
6062 return ret;
6063}
6064
6065static upb_msgval upb_msgval_fromval(upb_value val) {
6066 upb_msgval ret;
6067 UPB_UNUSED(val);
6068 memset(&ret, 0, sizeof(upb_msgval)); /* XXX */
6069 return ret;
6070}
6071
6072static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
6073 switch (type) {
6074 case UPB_TYPE_FLOAT: return UPB_CTYPE_FLOAT;
6075 case UPB_TYPE_DOUBLE: return UPB_CTYPE_DOUBLE;
6076 case UPB_TYPE_BOOL: return UPB_CTYPE_BOOL;
6077 case UPB_TYPE_BYTES:
6078 case UPB_TYPE_MESSAGE:
6079 case UPB_TYPE_STRING: return UPB_CTYPE_CONSTPTR;
6080 case UPB_TYPE_ENUM:
6081 case UPB_TYPE_INT32: return UPB_CTYPE_INT32;
6082 case UPB_TYPE_UINT32: return UPB_CTYPE_UINT32;
6083 case UPB_TYPE_INT64: return UPB_CTYPE_INT64;
6084 case UPB_TYPE_UINT64: return UPB_CTYPE_UINT64;
6085 default: UPB_ASSERT(false); return 0;
6086 }
6087}
6088
6089static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
6090 switch (upb_fielddef_type(f)) {
6091 case UPB_TYPE_FLOAT:
6092 return upb_msgval_float(upb_fielddef_defaultfloat(f));
6093 case UPB_TYPE_DOUBLE:
6094 return upb_msgval_double(upb_fielddef_defaultdouble(f));
6095 case UPB_TYPE_BOOL:
6096 return upb_msgval_bool(upb_fielddef_defaultbool(f));
6097 case UPB_TYPE_STRING:
6098 case UPB_TYPE_BYTES: {
6099 size_t len;
6100 const char *ptr = upb_fielddef_defaultstr(f, &len);
6101 return upb_msgval_makestr(ptr, len);
6102 }
6103 case UPB_TYPE_MESSAGE:
6104 return upb_msgval_msg(NULL);
6105 case UPB_TYPE_ENUM:
6106 case UPB_TYPE_INT32:
6107 return upb_msgval_int32(upb_fielddef_defaultint32(f));
6108 case UPB_TYPE_UINT32:
6109 return upb_msgval_uint32(upb_fielddef_defaultuint32(f));
6110 case UPB_TYPE_INT64:
6111 return upb_msgval_int64(upb_fielddef_defaultint64(f));
6112 case UPB_TYPE_UINT64:
6113 return upb_msgval_uint64(upb_fielddef_defaultuint64(f));
6114 default:
6115 UPB_ASSERT(false);
6116 return upb_msgval_msg(NULL);
6117 }
6118}
6119
6120
6121/** upb_msglayout *************************************************************/
6122
6123struct upb_msglayout {
6124 struct upb_msglayout_msginit_v1 data;
6125};
6126
6127static void upb_msglayout_free(upb_msglayout *l) {
6128 upb_gfree(l->data.default_msg);
6129 upb_gfree(l);
6130}
6131
6132static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
6133 size_t ret;
6134
6135 l->data.size = align_up(l->data.size, size);
6136 ret = l->data.size;
6137 l->data.size += size;
6138 return ret;
6139}
6140
6141static uint32_t upb_msglayout_offset(const upb_msglayout *l,
6142 const upb_fielddef *f) {
6143 return l->data.fields[upb_fielddef_index(f)].offset;
6144}
6145
6146static uint32_t upb_msglayout_hasbit(const upb_msglayout *l,
6147 const upb_fielddef *f) {
6148 return l->data.fields[upb_fielddef_index(f)].hasbit;
6149}
6150
6151static bool upb_msglayout_initdefault(upb_msglayout *l, const upb_msgdef *m) {
6152 upb_msg_field_iter it;
6153
6154 if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->data.size) {
6155 /* Allocate default message and set default values in it. */
6156 l->data.default_msg = upb_gmalloc(l->data.size);
6157 if (!l->data.default_msg) {
6158 return false;
6159 }
6160
6161 memset(l->data.default_msg, 0, l->data.size);
6162
6163 for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
6164 upb_msg_field_next(&it)) {
6165 const upb_fielddef* f = upb_msg_iter_field(&it);
6166
6167 if (upb_fielddef_containingoneof(f)) {
6168 continue;
6169 }
6170
6171 /* TODO(haberman): handle strings. */
6172 if (!upb_fielddef_isstring(f) &&
6173 !upb_fielddef_issubmsg(f) &&
6174 !upb_fielddef_isseq(f)) {
6175 upb_msg_set(l->data.default_msg,
6176 upb_fielddef_index(f),
6177 upb_msgval_fromdefault(f),
6178 l);
6179 }
6180 }
6181 }
6182
6183 return true;
6184}
6185
6186static bool upb_msglayout_init(const upb_msgdef *m,
6187 upb_msglayout *l,
6188 upb_msgfactory *factory) {
6189 upb_msg_field_iter it;
6190 upb_msg_oneof_iter oit;
6191 size_t hasbit;
6192 size_t submsg_count = 0;
6193 const upb_msglayout_msginit_v1 **submsgs;
6194 upb_msglayout_fieldinit_v1 *fields;
6195 upb_msglayout_oneofinit_v1 *oneofs;
6196
6197 for (upb_msg_field_begin(&it, m);
6198 !upb_msg_field_done(&it);
6199 upb_msg_field_next(&it)) {
6200 const upb_fielddef* f = upb_msg_iter_field(&it);
6201 if (upb_fielddef_issubmsg(f)) {
6202 submsg_count++;
6203 }
6204 }
6205
6206 memset(l, 0, sizeof(*l));
6207
6208 fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
6209 submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
6210 oneofs = upb_gmalloc(upb_msgdef_numoneofs(m) * sizeof(*oneofs));
6211
6212 if ((!fields && upb_msgdef_numfields(m)) ||
6213 (!submsgs && submsg_count) ||
6214 (!oneofs && upb_msgdef_numoneofs(m))) {
6215 /* OOM. */
6216 upb_gfree(fields);
6217 upb_gfree(submsgs);
6218 upb_gfree(oneofs);
6219 return false;
6220 }
6221
6222 l->data.field_count = upb_msgdef_numfields(m);
6223 l->data.oneof_count = upb_msgdef_numoneofs(m);
6224 l->data.fields = fields;
6225 l->data.submsgs = submsgs;
6226 l->data.oneofs = oneofs;
6227 l->data.is_proto2 = (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2);
6228
6229 /* Allocate data offsets in three stages:
6230 *
6231 * 1. hasbits.
6232 * 2. regular fields.
6233 * 3. oneof fields.
6234 *
6235 * OPT: There is a lot of room for optimization here to minimize the size.
6236 */
6237
6238 /* Allocate hasbits and set basic field attributes. */
6239 submsg_count = 0;
6240 for (upb_msg_field_begin(&it, m), hasbit = 0;
6241 !upb_msg_field_done(&it);
6242 upb_msg_field_next(&it)) {
6243 const upb_fielddef* f = upb_msg_iter_field(&it);
6244 upb_msglayout_fieldinit_v1 *field = &fields[upb_fielddef_index(f)];
6245
6246 field->number = upb_fielddef_number(f);
6247 field->descriptortype = upb_fielddef_descriptortype(f);
6248 field->label = upb_fielddef_label(f);
6249
6250 if (upb_fielddef_containingoneof(f)) {
6251 field->oneof_index = upb_oneofdef_index(upb_fielddef_containingoneof(f));
6252 } else {
6253 field->oneof_index = UPB_NOT_IN_ONEOF;
6254 }
6255
6256 if (upb_fielddef_issubmsg(f)) {
6257 const upb_msglayout *sub_layout =
6258 upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f));
6259 field->submsg_index = submsg_count++;
6260 submsgs[field->submsg_index] = &sub_layout->data;
6261 } else {
6262 field->submsg_index = UPB_NO_SUBMSG;
6263 }
6264
6265 if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
6266 field->hasbit = hasbit++;
6267 } else {
6268 field->hasbit = UPB_NO_HASBIT;
6269 }
6270 }
6271
6272 /* Account for space used by hasbits. */
6273 l->data.size = div_round_up(hasbit, 8);
6274
6275 /* Allocate non-oneof fields. */
6276 for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
6277 upb_msg_field_next(&it)) {
6278 const upb_fielddef* f = upb_msg_iter_field(&it);
6279 size_t field_size = upb_msg_fielddefsize(f);
6280 size_t index = upb_fielddef_index(f);
6281
6282 if (upb_fielddef_containingoneof(f)) {
6283 /* Oneofs are handled separately below. */
6284 continue;
6285 }
6286
6287 fields[index].offset = upb_msglayout_place(l, field_size);
6288 }
6289
6290 /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
6291 * and space for the actual data. */
6292 for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
6293 upb_msg_oneof_next(&oit)) {
6294 const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
6295 upb_oneof_iter fit;
6296
6297 size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
6298 upb_msglayout_oneofinit_v1 *oneof = &oneofs[upb_oneofdef_index(o)];
6299 size_t field_size = 0;
6300
6301 /* Calculate field size: the max of all field sizes. */
6302 for (upb_oneof_begin(&fit, o);
6303 !upb_oneof_done(&fit);
6304 upb_oneof_next(&fit)) {
6305 const upb_fielddef* f = upb_oneof_iter_field(&fit);
6306 field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
6307 }
6308
6309 /* Align and allocate case offset. */
6310 oneof->case_offset = upb_msglayout_place(l, case_size);
6311 oneof->data_offset = upb_msglayout_place(l, field_size);
6312 }
6313
6314 /* Size of the entire structure should be a multiple of its greatest
6315 * alignment. TODO: track overall alignment for real? */
6316 l->data.size = align_up(l->data.size, 8);
6317
6318 return upb_msglayout_initdefault(l, m);
6319}
6320
6321
6322/** upb_msgfactory ************************************************************/
6323
6324struct upb_msgfactory {
6325 const upb_symtab *symtab; /* We own a ref. */
6326 upb_inttable layouts;
6327 upb_inttable mergehandlers;
6328};
6329
6330upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) {
6331 upb_msgfactory *ret = upb_gmalloc(sizeof(*ret));
6332
6333 ret->symtab = symtab;
6334 upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR);
6335 upb_inttable_init(&ret->mergehandlers, UPB_CTYPE_CONSTPTR);
6336
6337 return ret;
6338}
6339
6340void upb_msgfactory_free(upb_msgfactory *f) {
6341 upb_inttable_iter i;
6342 upb_inttable_begin(&i, &f->layouts);
6343 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
6344 upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i));
6345 upb_msglayout_free(l);
6346 }
6347
6348 upb_inttable_begin(&i, &f->mergehandlers);
6349 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
6350 const upb_handlers *h = upb_value_getconstptr(upb_inttable_iter_value(&i));
6351 upb_handlers_unref(h, f);
6352 }
6353
6354 upb_inttable_uninit(&f->layouts);
6355 upb_inttable_uninit(&f->mergehandlers);
6356 upb_gfree(f);
6357}
6358
6359const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) {
6360 return f->symtab;
6361}
6362
6363const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
6364 const upb_msgdef *m) {
6365 upb_value v;
6366 UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m);
6367 UPB_ASSERT(!upb_msgdef_mapentry(m));
6368
6369 if (upb_inttable_lookupptr(&f->layouts, m, &v)) {
6370 UPB_ASSERT(upb_value_getptr(v));
6371 return upb_value_getptr(v);
6372 } else {
6373 /* In case of circular dependency, layout has to be inserted first. */
6374 upb_msglayout *l = upb_gmalloc(sizeof(*l));
6375 upb_msgfactory *mutable_f = (void*)f;
6376 upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
6377 UPB_ASSERT(l);
6378 if (!upb_msglayout_init(m, l, f)) {
6379 upb_msglayout_free(l);
6380 }
6381 return l;
6382 }
6383}
6384
6385/* Our handlers that we don't expose externally. */
6386
6387void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
6388 uint32_t ofs = (uintptr_t)hd;
6389 upb_alloc *alloc = upb_msg_alloc(msg);
6390 upb_msgval val;
6391 UPB_UNUSED(size_hint);
6392
6393 val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
6394
6395 upb_free(alloc, (void*)val.str.data);
6396 val.str.data = NULL;
6397 val.str.size = 0;
6398
6399 upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
6400 return msg;
6401}
6402
6403size_t upb_msg_str(void *msg, const void *hd, const char *ptr, size_t size,
6404 const upb_bufhandle *handle) {
6405 uint32_t ofs = (uintptr_t)hd;
6406 upb_alloc *alloc = upb_msg_alloc(msg);
6407 upb_msgval val;
6408 size_t newsize;
6409 UPB_UNUSED(handle);
6410
6411 val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
6412
6413 newsize = val.str.size + size;
6414 val.str.data = upb_realloc(alloc, (void*)val.str.data, val.str.size, newsize);
6415
6416 if (!val.str.data) {
6417 return false;
6418 }
6419
6420 memcpy((char*)val.str.data + val.str.size, ptr, size);
6421 val.str.size = newsize;
6422 upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
6423 return size;
6424}
6425
6426static void callback(const void *closure, upb_handlers *h) {
6427 upb_msgfactory *factory = (upb_msgfactory*)closure;
6428 const upb_msgdef *md = upb_handlers_msgdef(h);
6429 const upb_msglayout* layout = upb_msgfactory_getlayout(factory, md);
6430 upb_msg_field_iter i;
6431 UPB_UNUSED(factory);
6432
6433 for(upb_msg_field_begin(&i, md);
6434 !upb_msg_field_done(&i);
6435 upb_msg_field_next(&i)) {
6436 const upb_fielddef *f = upb_msg_iter_field(&i);
6437 size_t offset = upb_msglayout_offset(layout, f);
6438 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
6439 upb_handlerattr_sethandlerdata(&attr, (void*)offset);
6440
6441 if (upb_fielddef_isseq(f)) {
6442 } else if (upb_fielddef_isstring(f)) {
6443 upb_handlers_setstartstr(h, f, upb_msg_startstr, &attr);
6444 upb_handlers_setstring(h, f, upb_msg_str, &attr);
6445 } else {
6446 upb_msg_setscalarhandler(
6447 h, f, offset, upb_msglayout_hasbit(layout, f));
6448 }
6449 }
6450}
6451
6452const upb_handlers *upb_msgfactory_getmergehandlers(upb_msgfactory *f,
6453 const upb_msgdef *m) {
6454 upb_msgfactory *mutable_f = (void*)f;
6455
6456 /* TODO(haberman): properly cache these. */
6457 const upb_handlers *ret = upb_handlers_newfrozen(m, f, callback, f);
6458 upb_inttable_push(&mutable_f->mergehandlers, upb_value_constptr(ret));
6459
6460 return ret;
6461}
6462
6463const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f,
6464 const upb_handlers *h) {
6465 const upb_msgdef *md = upb_handlers_msgdef(h);
6466 return (const upb_visitorplan*)upb_msgfactory_getlayout(f, md);
6467}
6468
6469
6470/** upb_visitor ***************************************************************/
6471
6472struct upb_visitor {
6473 const upb_msglayout *layout;
6474 upb_sink *sink;
6475};
6476
6477static upb_selector_t getsel2(const upb_fielddef *f, upb_handlertype_t type) {
6478 upb_selector_t ret;
6479 bool ok = upb_handlers_getselector(f, type, &ret);
6480 UPB_ASSERT(ok);
6481 return ret;
6482}
6483
6484static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
6485 const upb_msglayout *layout) {
6486 int field_index = upb_fielddef_index(f);
6487 if (upb_fielddef_isseq(f)) {
6488 return upb_msgval_getarr(upb_msg_get(msg, field_index, layout)) != NULL;
6489 } else if (upb_msgdef_syntax(upb_fielddef_containingtype(f)) ==
6490 UPB_SYNTAX_PROTO2) {
6491 return upb_msg_has(msg, field_index, layout);
6492 } else {
6493 upb_msgval val = upb_msg_get(msg, field_index, layout);
6494 switch (upb_fielddef_type(f)) {
6495 case UPB_TYPE_FLOAT:
6496 return upb_msgval_getfloat(val) != 0;
6497 case UPB_TYPE_DOUBLE:
6498 return upb_msgval_getdouble(val) != 0;
6499 case UPB_TYPE_BOOL:
6500 return upb_msgval_getbool(val);
6501 case UPB_TYPE_ENUM:
6502 case UPB_TYPE_INT32:
6503 return upb_msgval_getint32(val) != 0;
6504 case UPB_TYPE_UINT32:
6505 return upb_msgval_getuint32(val) != 0;
6506 case UPB_TYPE_INT64:
6507 return upb_msgval_getint64(val) != 0;
6508 case UPB_TYPE_UINT64:
6509 return upb_msgval_getuint64(val) != 0;
6510 case UPB_TYPE_STRING:
6511 case UPB_TYPE_BYTES:
6512 return upb_msgval_getstr(val).size > 0;
6513 case UPB_TYPE_MESSAGE:
6514 return upb_msgval_getmsg(val) != NULL;
6515 }
6516 UPB_UNREACHABLE();
6517 }
6518}
6519
6520static bool upb_visitor_visitmsg2(const upb_msg *msg,
6521 const upb_msglayout *layout, upb_sink *sink,
6522 int depth) {
6523 const upb_msgdef *md = upb_handlers_msgdef(sink->handlers);
6524 upb_msg_field_iter i;
6525 upb_status status;
6526
6527 upb_sink_startmsg(sink);
6528
6529 /* Protect against cycles (possible because users may freely reassign message
6530 * and repeated fields) by imposing a maximum recursion depth. */
6531 if (depth > ENCODE_MAX_NESTING) {
6532 return false;
6533 }
6534
6535 for (upb_msg_field_begin(&i, md);
6536 !upb_msg_field_done(&i);
6537 upb_msg_field_next(&i)) {
6538 upb_fielddef *f = upb_msg_iter_field(&i);
6539 upb_msgval val;
6540
6541 if (!upb_visitor_hasfield(msg, f, layout)) {
6542 continue;
6543 }
6544
6545 val = upb_msg_get(msg, upb_fielddef_index(f), layout);
6546
6547 if (upb_fielddef_isseq(f)) {
6548 const upb_array *arr = upb_msgval_getarr(val);
6549 UPB_ASSERT(arr);
6550 /* TODO: putary(ary, f, sink, depth);*/
6551 } else if (upb_fielddef_issubmsg(f)) {
6552 const upb_map *map = upb_msgval_getmap(val);
6553 UPB_ASSERT(map);
6554 /* TODO: putmap(map, f, sink, depth);*/
6555 } else if (upb_fielddef_isstring(f)) {
6556 /* TODO putstr(); */
6557 } else {
6558 upb_selector_t sel = getsel2(f, upb_handlers_getprimitivehandlertype(f));
6559 UPB_ASSERT(upb_fielddef_isprimitive(f));
6560
6561 switch (upb_fielddef_type(f)) {
6562 case UPB_TYPE_FLOAT:
6563 CHECK_TRUE(upb_sink_putfloat(sink, sel, upb_msgval_getfloat(val)));
6564 break;
6565 case UPB_TYPE_DOUBLE:
6566 CHECK_TRUE(upb_sink_putdouble(sink, sel, upb_msgval_getdouble(val)));
6567 break;
6568 case UPB_TYPE_BOOL:
6569 CHECK_TRUE(upb_sink_putbool(sink, sel, upb_msgval_getbool(val)));
6570 break;
6571 case UPB_TYPE_ENUM:
6572 case UPB_TYPE_INT32:
6573 CHECK_TRUE(upb_sink_putint32(sink, sel, upb_msgval_getint32(val)));
6574 break;
6575 case UPB_TYPE_UINT32:
6576 CHECK_TRUE(upb_sink_putuint32(sink, sel, upb_msgval_getuint32(val)));
6577 break;
6578 case UPB_TYPE_INT64:
6579 CHECK_TRUE(upb_sink_putint64(sink, sel, upb_msgval_getint64(val)));
6580 break;
6581 case UPB_TYPE_UINT64:
6582 CHECK_TRUE(upb_sink_putuint64(sink, sel, upb_msgval_getuint64(val)));
6583 break;
6584 case UPB_TYPE_STRING:
6585 case UPB_TYPE_BYTES:
6586 case UPB_TYPE_MESSAGE:
6587 UPB_UNREACHABLE();
6588 }
6589 }
6590 }
6591
6592 upb_sink_endmsg(sink, &status);
6593 return true;
6594}
6595
6596upb_visitor *upb_visitor_create(upb_env *e, const upb_visitorplan *vp,
6597 upb_sink *output) {
6598 upb_visitor *visitor = upb_env_malloc(e, sizeof(*visitor));
6599 visitor->layout = (const upb_msglayout*)vp;
6600 visitor->sink = output;
6601 return visitor;
6602}
6603
6604bool upb_visitor_visitmsg(upb_visitor *visitor, const upb_msg *msg) {
6605 return upb_visitor_visitmsg2(msg, visitor->layout, visitor->sink, 0);
6606}
6607
6608
6609/** upb_msg *******************************************************************/
6610
6611/* If we always read/write as a consistent type to each address, this shouldn't
6612 * violate aliasing.
6613 */
6614#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
6615
6616/* Internal members of a upb_msg. We can change this without breaking binary
6617 * compatibility. We put these before the user's data. The user's upb_msg*
6618 * points after the upb_msg_internal. */
6619
6620/* Used when a message is not extendable. */
6621typedef struct {
6622 /* TODO(haberman): add unknown fields. */
6623 upb_alloc *alloc;
6624} upb_msg_internal;
6625
6626/* Used when a message is extendable. */
6627typedef struct {
6628 upb_inttable *extdict;
6629 upb_msg_internal base;
6630} upb_msg_internal_withext;
6631
6632static int upb_msg_internalsize(const upb_msglayout *l) {
6633 return sizeof(upb_msg_internal) - l->data.extendable * sizeof(void*);
6634}
6635
6636static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
6637 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
6638}
6639
6640static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
6641 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
6642}
6643
6644static upb_msg_internal_withext *upb_msg_getinternalwithext(
6645 upb_msg *msg, const upb_msglayout *l) {
6646 UPB_ASSERT(l->data.extendable);
6647 return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
6648}
6649
6650static const upb_msglayout_fieldinit_v1 *upb_msg_checkfield(
6651 int field_index, const upb_msglayout *l) {
6652 UPB_ASSERT(field_index >= 0 && field_index < l->data.field_count);
6653 return &l->data.fields[field_index];
6654}
6655
6656static bool upb_msg_inoneof(const upb_msglayout_fieldinit_v1 *field) {
6657 return field->oneof_index != UPB_NOT_IN_ONEOF;
6658}
6659
6660static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
6661 const upb_msglayout *l) {
6662 const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
6663 UPB_ASSERT(upb_msg_inoneof(field));
6664 return PTR_AT(msg, l->data.oneofs[field->oneof_index].case_offset, uint32_t);
6665}
6666
6667size_t upb_msg_sizeof(const upb_msglayout *l) {
6668 return l->data.size + upb_msg_internalsize(l);
6669}
6670
6671upb_msg *upb_msg_init(void *mem, const upb_msglayout *l, upb_alloc *a) {
6672 upb_msg *msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
6673
6674 /* Initialize normal members. */
6675 if (l->data.default_msg) {
6676 memcpy(msg, l->data.default_msg, l->data.size);
6677 } else {
6678 memset(msg, 0, l->data.size);
6679 }
6680
6681 /* Initialize internal members. */
6682 upb_msg_getinternal(msg)->alloc = a;
6683
6684 if (l->data.extendable) {
6685 upb_msg_getinternalwithext(msg, l)->extdict = NULL;
6686 }
6687
6688 return msg;
6689}
6690
6691void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
6692 if (l->data.extendable) {
6693 upb_inttable *ext_dict = upb_msg_getinternalwithext(msg, l)->extdict;
6694 if (ext_dict) {
6695 upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg));
6696 upb_free(upb_msg_alloc(msg), ext_dict);
6697 }
6698 }
6699
6700 return VOIDPTR_AT(msg, -upb_msg_internalsize(l));
6701}
6702
6703upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
6704 void *mem = upb_malloc(a, upb_msg_sizeof(l));
6705 return mem ? upb_msg_init(mem, l, a) : NULL;
6706}
6707
6708void upb_msg_free(upb_msg *msg, const upb_msglayout *l) {
6709 upb_free(upb_msg_alloc(msg), upb_msg_uninit(msg, l));
6710}
6711
6712upb_alloc *upb_msg_alloc(const upb_msg *msg) {
6713 return upb_msg_getinternal_const(msg)->alloc;
6714}
6715
6716bool upb_msg_has(const upb_msg *msg,
6717 int field_index,
6718 const upb_msglayout *l) {
6719 const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
6720
6721 UPB_ASSERT(l->data.is_proto2);
6722
6723 if (upb_msg_inoneof(field)) {
6724 /* Oneofs are set when the oneof number is set to this field. */
6725 return *upb_msg_oneofcase(msg, field_index, l) == field->number;
6726 } else {
6727 /* Other fields are set when their hasbit is set. */
6728 uint32_t hasbit = l->data.fields[field_index].hasbit;
6729 return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
6730 }
6731}
6732
6733upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
6734 const upb_msglayout *l) {
6735 const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
6736 int size = upb_msg_fieldsize(field);
6737
6738 if (upb_msg_inoneof(field)) {
6739 if (*upb_msg_oneofcase(msg, field_index, l) == field->number) {
6740 size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
6741 return upb_msgval_read(msg, ofs, size);
6742 } else {
6743 /* Return default. */
6744 return upb_msgval_read(l->data.default_msg, field->offset, size);
6745 }
6746 } else {
6747 return upb_msgval_read(msg, field->offset, size);
6748 }
6749}
6750
6751void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
6752 const upb_msglayout *l) {
6753 const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
6754 int size = upb_msg_fieldsize(field);
6755
6756 if (upb_msg_inoneof(field)) {
6757 size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
6758 *upb_msg_oneofcase(msg, field_index, l) = field->number;
6759 upb_msgval_write(msg, ofs, val, size);
6760 } else {
6761 upb_msgval_write(msg, field->offset, val, size);
6762 }
6763}
6764
6765
6766/** upb_array *****************************************************************/
6767
6768#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
6769
6770size_t upb_array_sizeof(upb_fieldtype_t type) {
6771 UPB_UNUSED(type);
6772 return sizeof(upb_array);
6773}
6774
6775void upb_array_init(upb_array *arr, upb_fieldtype_t type, upb_alloc *alloc) {
6776 arr->type = type;
6777 arr->data = NULL;
6778 arr->len = 0;
6779 arr->size = 0;
6780 arr->element_size = upb_msgval_sizeof(type);
6781 arr->alloc = alloc;
6782}
6783
6784void upb_array_uninit(upb_array *arr) {
6785 upb_free(arr->alloc, arr->data);
6786}
6787
6788upb_array *upb_array_new(upb_fieldtype_t type, upb_alloc *a) {
6789 upb_array *ret = upb_malloc(a, upb_array_sizeof(type));
6790
6791 if (ret) {
6792 upb_array_init(ret, type, a);
6793 }
6794
6795 return ret;
6796}
6797
6798void upb_array_free(upb_array *arr) {
6799 upb_array_uninit(arr);
6800 upb_free(arr->alloc, arr);
6801}
6802
6803size_t upb_array_size(const upb_array *arr) {
6804 return arr->len;
6805}
6806
6807upb_fieldtype_t upb_array_type(const upb_array *arr) {
6808 return arr->type;
6809}
6810
6811upb_msgval upb_array_get(const upb_array *arr, size_t i) {
6812 UPB_ASSERT(i < arr->len);
6813 return upb_msgval_read(arr->data, i * arr->element_size, arr->element_size);
6814}
6815
6816bool upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
6817 UPB_ASSERT(i <= arr->len);
6818
6819 if (i == arr->len) {
6820 /* Extending the array. */
6821
6822 if (i == arr->size) {
6823 /* Need to reallocate. */
6824 size_t new_size = UPB_MAX(arr->size * 2, 8);
6825 size_t new_bytes = new_size * arr->element_size;
6826 size_t old_bytes = arr->size * arr->element_size;
6827 upb_msgval *new_data =
6828 upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
6829
6830 if (!new_data) {
6831 return false;
6832 }
6833
6834 arr->data = new_data;
6835 arr->size = new_size;
6836 }
6837
6838 arr->len = i + 1;
6839 }
6840
6841 upb_msgval_write(arr->data, i * arr->element_size, val, arr->element_size);
6842 return true;
6843}
6844
6845
6846/** upb_map *******************************************************************/
6847
6848struct upb_map {
6849 upb_fieldtype_t key_type;
6850 upb_fieldtype_t val_type;
6851 /* We may want to optimize this to use inttable where possible, for greater
6852 * efficiency and lower memory footprint. */
6853 upb_strtable strtab;
6854 upb_alloc *alloc;
6855};
6856
6857static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
6858 const char **out_key, size_t *out_len) {
6859 switch (type) {
6860 case UPB_TYPE_STRING:
6861 /* Point to string data of the input key. */
6862 *out_key = key->str.data;
6863 *out_len = key->str.size;
6864 return;
6865 case UPB_TYPE_BOOL:
6866 case UPB_TYPE_INT32:
6867 case UPB_TYPE_UINT32:
6868 case UPB_TYPE_INT64:
6869 case UPB_TYPE_UINT64:
6870 /* Point to the key itself. XXX: big-endian. */
6871 *out_key = (const char*)key;
6872 *out_len = upb_msgval_sizeof(type);
6873 return;
6874 case UPB_TYPE_BYTES:
6875 case UPB_TYPE_DOUBLE:
6876 case UPB_TYPE_ENUM:
6877 case UPB_TYPE_FLOAT:
6878 case UPB_TYPE_MESSAGE:
6879 break; /* Cannot be a map key. */
6880 }
6881 UPB_UNREACHABLE();
6882}
6883
6884static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
6885 size_t len) {
6886 switch (type) {
6887 case UPB_TYPE_STRING:
6888 return upb_msgval_makestr(key, len);
6889 case UPB_TYPE_BOOL:
6890 case UPB_TYPE_INT32:
6891 case UPB_TYPE_UINT32:
6892 case UPB_TYPE_INT64:
6893 case UPB_TYPE_UINT64:
6894 return upb_msgval_read(key, 0, upb_msgval_sizeof(type));
6895 case UPB_TYPE_BYTES:
6896 case UPB_TYPE_DOUBLE:
6897 case UPB_TYPE_ENUM:
6898 case UPB_TYPE_FLOAT:
6899 case UPB_TYPE_MESSAGE:
6900 break; /* Cannot be a map key. */
6901 }
6902 UPB_UNREACHABLE();
6903}
6904
6905size_t upb_map_sizeof(upb_fieldtype_t ktype, upb_fieldtype_t vtype) {
6906 /* Size does not currently depend on key/value type. */
6907 UPB_UNUSED(ktype);
6908 UPB_UNUSED(vtype);
6909 return sizeof(upb_map);
6910}
6911
6912bool upb_map_init(upb_map *map, upb_fieldtype_t ktype, upb_fieldtype_t vtype,
6913 upb_alloc *a) {
6914 upb_ctype_t vtabtype = upb_fieldtotabtype(vtype);
6915 UPB_ASSERT(upb_fieldtype_mapkeyok(ktype));
6916 map->key_type = ktype;
6917 map->val_type = vtype;
6918 map->alloc = a;
6919
6920 if (!upb_strtable_init2(&map->strtab, vtabtype, a)) {
6921 return false;
6922 }
6923
6924 return true;
6925}
6926
6927void upb_map_uninit(upb_map *map) {
6928 upb_strtable_uninit2(&map->strtab, map->alloc);
6929}
6930
6931upb_map *upb_map_new(upb_fieldtype_t ktype, upb_fieldtype_t vtype,
6932 upb_alloc *a) {
6933 upb_map *map = upb_malloc(a, upb_map_sizeof(ktype, vtype));
6934
6935 if (!map) {
6936 return NULL;
6937 }
6938
6939 if (!upb_map_init(map, ktype, vtype, a)) {
6940 return NULL;
6941 }
6942
6943 return map;
6944}
6945
6946void upb_map_free(upb_map *map) {
6947 upb_map_uninit(map);
6948 upb_free(map->alloc, map);
6949}
6950
6951size_t upb_map_size(const upb_map *map) {
6952 return upb_strtable_count(&map->strtab);
6953}
6954
6955upb_fieldtype_t upb_map_keytype(const upb_map *map) {
6956 return map->key_type;
6957}
6958
6959upb_fieldtype_t upb_map_valuetype(const upb_map *map) {
6960 return map->val_type;
6961}
6962
6963bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
6964 upb_value tabval;
6965 const char *key_str;
6966 size_t key_len;
6967 bool ret;
6968
6969 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
6970 ret = upb_strtable_lookup2(&map->strtab, key_str, key_len, &tabval);
6971 if (ret) {
6972 memcpy(val, &tabval, sizeof(tabval));
6973 }
6974
6975 return ret;
6976}
6977
6978bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
6979 upb_msgval *removed) {
6980 const char *key_str;
6981 size_t key_len;
6982 upb_value tabval = upb_toval(val);
6983 upb_value removedtabval;
6984 upb_alloc *a = map->alloc;
6985
6986 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
6987
6988 /* TODO(haberman): add overwrite operation to minimize number of lookups. */
6989 if (upb_strtable_lookup2(&map->strtab, key_str, key_len, NULL)) {
6990 upb_strtable_remove3(&map->strtab, key_str, key_len, &removedtabval, a);
6991 memcpy(&removed, &removedtabval, sizeof(removed));
6992 }
6993
6994 return upb_strtable_insert3(&map->strtab, key_str, key_len, tabval, a);
6995}
6996
6997bool upb_map_del(upb_map *map, upb_msgval key) {
6998 const char *key_str;
6999 size_t key_len;
7000 upb_alloc *a = map->alloc;
7001
7002 upb_map_tokey(map->key_type, &key, &key_str, &key_len);
7003 return upb_strtable_remove3(&map->strtab, key_str, key_len, NULL, a);
7004}
7005
7006
7007/** upb_mapiter ***************************************************************/
7008
7009struct upb_mapiter {
7010 upb_strtable_iter iter;
7011 upb_fieldtype_t key_type;
7012};
7013
7014size_t upb_mapiter_sizeof() {
7015 return sizeof(upb_mapiter);
7016}
7017
7018void upb_mapiter_begin(upb_mapiter *i, const upb_map *map) {
7019 upb_strtable_begin(&i->iter, &map->strtab);
7020 i->key_type = map->key_type;
7021}
7022
7023upb_mapiter *upb_mapiter_new(const upb_map *t, upb_alloc *a) {
7024 upb_mapiter *ret = upb_malloc(a, upb_mapiter_sizeof());
7025
7026 if (!ret) {
7027 return NULL;
7028 }
7029
7030 upb_mapiter_begin(ret, t);
7031 return ret;
7032}
7033
7034void upb_mapiter_free(upb_mapiter *i, upb_alloc *a) {
7035 upb_free(a, i);
7036}
7037
7038void upb_mapiter_next(upb_mapiter *i) {
7039 upb_strtable_next(&i->iter);
7040}
7041
7042bool upb_mapiter_done(const upb_mapiter *i) {
7043 return upb_strtable_done(&i->iter);
7044}
7045
7046upb_msgval upb_mapiter_key(const upb_mapiter *i) {
7047 return upb_map_fromkey(i->key_type, upb_strtable_iter_key(&i->iter),
7048 upb_strtable_iter_keylength(&i->iter));
7049}
7050
7051upb_msgval upb_mapiter_value(const upb_mapiter *i) {
7052 return upb_msgval_fromval(upb_strtable_iter_value(&i->iter));
7053}
7054
7055void upb_mapiter_setdone(upb_mapiter *i) {
7056 upb_strtable_iter_setdone(&i->iter);
7057}
7058
7059bool upb_mapiter_isequal(const upb_mapiter *i1, const upb_mapiter *i2) {
7060 return upb_strtable_iter_isequal(&i1->iter, &i2->iter);
7061}
7062
7063
7064/** Handlers for upb_msg ******************************************************/
7065
7066typedef struct {
7067 size_t offset;
7068 int32_t hasbit;
7069} upb_msg_handlerdata;
7070
7071/* Fallback implementation if the handler is not specialized by the producer. */
7072#define MSG_WRITER(type, ctype) \
7073 bool upb_msg_set ## type (void *c, const void *hd, ctype val) { \
7074 uint8_t *m = c; \
7075 const upb_msg_handlerdata *d = hd; \
7076 if (d->hasbit > 0) \
7077 *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
7078 *(ctype*)&m[d->offset] = val; \
7079 return true; \
7080 } \
7081
7082MSG_WRITER(double, double)
7083MSG_WRITER(float, float)
7084MSG_WRITER(int32, int32_t)
7085MSG_WRITER(int64, int64_t)
7086MSG_WRITER(uint32, uint32_t)
7087MSG_WRITER(uint64, uint64_t)
7088MSG_WRITER(bool, bool)
7089
7090bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f,
7091 size_t offset, int32_t hasbit) {
7092 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
7093 bool ok;
7094
7095 upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d));
7096 if (!d) return false;
7097 d->offset = offset;
7098 d->hasbit = hasbit;
7099
7100 upb_handlerattr_sethandlerdata(&attr, d);
7101 upb_handlerattr_setalwaysok(&attr, true);
7102 upb_handlers_addcleanup(h, d, upb_gfree);
7103
7104#define TYPE(u, l) \
7105 case UPB_TYPE_##u: \
7106 ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break;
7107
7108 ok = false;
7109
7110 switch (upb_fielddef_type(f)) {
7111 TYPE(INT64, int64);
7112 TYPE(INT32, int32);
7113 TYPE(ENUM, int32);
7114 TYPE(UINT64, uint64);
7115 TYPE(UINT32, uint32);
7116 TYPE(DOUBLE, double);
7117 TYPE(FLOAT, float);
7118 TYPE(BOOL, bool);
7119 default: UPB_ASSERT(false); break;
7120 }
7121#undef TYPE
7122
7123 upb_handlerattr_uninit(&attr);
7124 return ok;
7125}
7126
7127bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
7128 upb_selector_t s,
7129 upb_fieldtype_t *type,
7130 size_t *offset,
7131 int32_t *hasbit) {
7132 const upb_msg_handlerdata *d;
7133 upb_func *f = upb_handlers_gethandler(h, s);
7134
7135 if ((upb_int64_handlerfunc*)f == upb_msg_setint64) {
7136 *type = UPB_TYPE_INT64;
7137 } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) {
7138 *type = UPB_TYPE_INT32;
7139 } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) {
7140 *type = UPB_TYPE_UINT64;
7141 } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) {
7142 *type = UPB_TYPE_UINT32;
7143 } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) {
7144 *type = UPB_TYPE_DOUBLE;
7145 } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) {
7146 *type = UPB_TYPE_FLOAT;
7147 } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) {
7148 *type = UPB_TYPE_BOOL;
7149 } else {
7150 return false;
7151 }
7152
7153 d = upb_handlers_gethandlerdata(h, s);
7154 *offset = d->offset;
7155 *hasbit = d->hasbit;
7156 return true;
7157}
7158/*
7159** upb::RefCounted Implementation
7160**
7161** Our key invariants are:
7162** 1. reference cycles never span groups
7163** 2. for ref2(to, from), we increment to's count iff group(from) != group(to)
7164**
7165** The previous two are how we avoid leaking cycles. Other important
7166** invariants are:
7167** 3. for mutable objects "from" and "to", if there exists a ref2(to, from)
7168** this implies group(from) == group(to). (In practice, what we implement
7169** is even stronger; "from" and "to" will share a group if there has *ever*
7170** been a ref2(to, from), but all that is necessary for correctness is the
7171** weaker one).
7172** 4. mutable and immutable objects are never in the same group.
7173*/
7174
7175
7176#include <setjmp.h>
7177
7178static void freeobj(upb_refcounted *o);
7179
7180const char untracked_val;
7181const void *UPB_UNTRACKED_REF = &untracked_val;
7182
7183/* arch-specific atomic primitives *******************************************/
7184
7185#ifdef UPB_THREAD_UNSAFE /*---------------------------------------------------*/
7186
7187static void atomic_inc(uint32_t *a) { (*a)++; }
7188static bool atomic_dec(uint32_t *a) { return --(*a) == 0; }
7189
7190#elif defined(__GNUC__) || defined(__clang__) /*------------------------------*/
7191
7192static void atomic_inc(uint32_t *a) { __sync_fetch_and_add(a, 1); }
7193static bool atomic_dec(uint32_t *a) { return __sync_sub_and_fetch(a, 1) == 0; }
7194
7195#elif defined(WIN32) /*-------------------------------------------------------*/
7196
7197#include <Windows.h>
7198
7199static void atomic_inc(upb_atomic_t *a) { InterlockedIncrement(&a->val); }
7200static bool atomic_dec(upb_atomic_t *a) {
7201 return InterlockedDecrement(&a->val) == 0;
7202}
7203
7204#else
7205#error Atomic primitives not defined for your platform/CPU. \
7206 Implement them or compile with UPB_THREAD_UNSAFE.
7207#endif
7208
7209/* All static objects point to this refcount.
7210 * It is special-cased in ref/unref below. */
7211uint32_t static_refcount = -1;
7212
7213/* We can avoid atomic ops for statically-declared objects.
7214 * This is a minor optimization but nice since we can avoid degrading under
7215 * contention in this case. */
7216
7217static void refgroup(uint32_t *group) {
7218 if (group != &static_refcount)
7219 atomic_inc(group);
7220}
7221
7222static bool unrefgroup(uint32_t *group) {
7223 if (group == &static_refcount) {
7224 return false;
7225 } else {
7226 return atomic_dec(group);
7227 }
7228}
7229
7230
7231/* Reference tracking (debug only) ********************************************/
7232
7233#ifdef UPB_DEBUG_REFS
7234
7235#ifdef UPB_THREAD_UNSAFE
7236
7237static void upb_lock() {}
7238static void upb_unlock() {}
7239
7240#else
7241
7242/* User must define functions that lock/unlock a global mutex and link this
7243 * file against them. */
7244void upb_lock();
7245void upb_unlock();
7246
7247#endif
7248
7249/* UPB_DEBUG_REFS mode counts on being able to malloc() memory in some
7250 * code-paths that can normally never fail, like upb_refcounted_ref(). Since
7251 * we have no way to propagage out-of-memory errors back to the user, and since
7252 * these errors can only occur in UPB_DEBUG_REFS mode, we use an allocator that
7253 * immediately aborts on failure (avoiding the global allocator, which might
7254 * inject failures). */
7255
7256#include <stdlib.h>
7257
7258static void *upb_debugrefs_allocfunc(upb_alloc *alloc, void *ptr,
7259 size_t oldsize, size_t size) {
7260 UPB_UNUSED(alloc);
7261 UPB_UNUSED(oldsize);
7262 if (size == 0) {
7263 free(ptr);
7264 return NULL;
7265 } else {
7266 void *ret = realloc(ptr, size);
7267
7268 if (!ret) {
7269 abort();
7270 }
7271
7272 return ret;
7273 }
7274}
7275
7276upb_alloc upb_alloc_debugrefs = {&upb_debugrefs_allocfunc};
7277
7278typedef struct {
7279 int count; /* How many refs there are (duplicates only allowed for ref2). */
7280 bool is_ref2;
7281} trackedref;
7282
7283static trackedref *trackedref_new(bool is_ref2) {
7284 trackedref *ret = upb_malloc(&upb_alloc_debugrefs, sizeof(*ret));
7285 ret->count = 1;
7286 ret->is_ref2 = is_ref2;
7287 return ret;
7288}
7289
7290static void track(const upb_refcounted *r, const void *owner, bool ref2) {
7291 upb_value v;
7292
7293 UPB_ASSERT(owner);
7294 if (owner == UPB_UNTRACKED_REF) return;
7295
7296 upb_lock();
7297 if (upb_inttable_lookupptr(r->refs, owner, &v)) {
7298 trackedref *ref = upb_value_getptr(v);
7299 /* Since we allow multiple ref2's for the same to/from pair without
7300 * allocating separate memory for each one, we lose the fine-grained
7301 * tracking behavior we get with regular refs. Since ref2s only happen
7302 * inside upb, we'll accept this limitation until/unless there is a really
7303 * difficult upb-internal bug that can't be figured out without it. */
7304 UPB_ASSERT(ref2);
7305 UPB_ASSERT(ref->is_ref2);
7306 ref->count++;
7307 } else {
7308 trackedref *ref = trackedref_new(ref2);
7309 upb_inttable_insertptr2(r->refs, owner, upb_value_ptr(ref),
7310 &upb_alloc_debugrefs);
7311 if (ref2) {
7312 /* We know this cast is safe when it is a ref2, because it's coming from
7313 * another refcounted object. */
7314 const upb_refcounted *from = owner;
7315 UPB_ASSERT(!upb_inttable_lookupptr(from->ref2s, r, NULL));
7316 upb_inttable_insertptr2(from->ref2s, r, upb_value_ptr(NULL),
7317 &upb_alloc_debugrefs);
7318 }
7319 }
7320 upb_unlock();
7321}
7322
7323static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
7324 upb_value v;
7325 bool found;
7326 trackedref *ref;
7327
7328 UPB_ASSERT(owner);
7329 if (owner == UPB_UNTRACKED_REF) return;
7330
7331 upb_lock();
7332 found = upb_inttable_lookupptr(r->refs, owner, &v);
7333 /* This assert will fail if an owner attempts to release a ref it didn't have. */
7334 UPB_ASSERT(found);
7335 ref = upb_value_getptr(v);
7336 UPB_ASSERT(ref->is_ref2 == ref2);
7337 if (--ref->count == 0) {
7338 free(ref);
7339 upb_inttable_removeptr(r->refs, owner, NULL);
7340 if (ref2) {
7341 /* We know this cast is safe when it is a ref2, because it's coming from
7342 * another refcounted object. */
7343 const upb_refcounted *from = owner;
7344 bool removed = upb_inttable_removeptr(from->ref2s, r, NULL);
7345 UPB_ASSERT(removed);
7346 }
7347 }
7348 upb_unlock();
7349}
7350
7351static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
7352 upb_value v;
7353 bool found;
7354 trackedref *ref;
7355
7356 upb_lock();
7357 found = upb_inttable_lookupptr(r->refs, owner, &v);
7358 UPB_ASSERT(found);
7359 ref = upb_value_getptr(v);
7360 UPB_ASSERT(ref->is_ref2 == ref2);
7361 upb_unlock();
7362}
7363
7364/* Populates the given UPB_CTYPE_INT32 inttable with counts of ref2's that
7365 * originate from the given owner. */
7366static void getref2s(const upb_refcounted *owner, upb_inttable *tab) {
7367 upb_inttable_iter i;
7368
7369 upb_lock();
7370 upb_inttable_begin(&i, owner->ref2s);
7371 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
7372 upb_value v;
7373 upb_value count;
7374 trackedref *ref;
7375 bool found;
7376
7377 upb_refcounted *to = (upb_refcounted*)upb_inttable_iter_key(&i);
7378
7379 /* To get the count we need to look in the target's table. */
7380 found = upb_inttable_lookupptr(to->refs, owner, &v);
7381 UPB_ASSERT(found);
7382 ref = upb_value_getptr(v);
7383 count = upb_value_int32(ref->count);
7384
7385 upb_inttable_insertptr2(tab, to, count, &upb_alloc_debugrefs);
7386 }
7387 upb_unlock();
7388}
7389
7390typedef struct {
7391 upb_inttable ref2;
7392 const upb_refcounted *obj;
7393} check_state;
7394
7395static void visit_check(const upb_refcounted *obj, const upb_refcounted *subobj,
7396 void *closure) {
7397 check_state *s = closure;
7398 upb_inttable *ref2 = &s->ref2;
7399 upb_value v;
7400 bool removed;
7401 int32_t newcount;
7402
7403 UPB_ASSERT(obj == s->obj);
7404 UPB_ASSERT(subobj);
7405 removed = upb_inttable_removeptr(ref2, subobj, &v);
7406 /* The following assertion will fail if the visit() function visits a subobj
7407 * that it did not have a ref2 on, or visits the same subobj too many times. */
7408 UPB_ASSERT(removed);
7409 newcount = upb_value_getint32(v) - 1;
7410 if (newcount > 0) {
7411 upb_inttable_insert2(ref2, (uintptr_t)subobj, upb_value_int32(newcount),
7412 &upb_alloc_debugrefs);
7413 }
7414}
7415
7416static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
7417 void *closure) {
7418 /* In DEBUG_REFS mode we know what existing ref2 refs there are, so we know
7419 * exactly the set of nodes that visit() should visit. So we verify visit()'s
7420 * correctness here. */
7421 check_state state;
7422 state.obj = r;
7423 upb_inttable_init2(&state.ref2, UPB_CTYPE_INT32, &upb_alloc_debugrefs);
7424 getref2s(r, &state.ref2);
7425
7426 /* This should visit any children in the ref2 table. */
7427 if (r->vtbl->visit) r->vtbl->visit(r, visit_check, &state);
7428
7429 /* This assertion will fail if the visit() function missed any children. */
7430 UPB_ASSERT(upb_inttable_count(&state.ref2) == 0);
7431 upb_inttable_uninit2(&state.ref2, &upb_alloc_debugrefs);
7432 if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
7433}
7434
7435static void trackinit(upb_refcounted *r) {
7436 r->refs = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->refs));
7437 r->ref2s = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->ref2s));
7438 upb_inttable_init2(r->refs, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
7439 upb_inttable_init2(r->ref2s, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
7440}
7441
7442static void trackfree(const upb_refcounted *r) {
7443 upb_inttable_uninit2(r->refs, &upb_alloc_debugrefs);
7444 upb_inttable_uninit2(r->ref2s, &upb_alloc_debugrefs);
7445 upb_free(&upb_alloc_debugrefs, r->refs);
7446 upb_free(&upb_alloc_debugrefs, r->ref2s);
7447}
7448
7449#else
7450
7451static void track(const upb_refcounted *r, const void *owner, bool ref2) {
7452 UPB_UNUSED(r);
7453 UPB_UNUSED(owner);
7454 UPB_UNUSED(ref2);
7455}
7456
7457static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
7458 UPB_UNUSED(r);
7459 UPB_UNUSED(owner);
7460 UPB_UNUSED(ref2);
7461}
7462
7463static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
7464 UPB_UNUSED(r);
7465 UPB_UNUSED(owner);
7466 UPB_UNUSED(ref2);
7467}
7468
7469static void trackinit(upb_refcounted *r) {
7470 UPB_UNUSED(r);
7471}
7472
7473static void trackfree(const upb_refcounted *r) {
7474 UPB_UNUSED(r);
7475}
7476
7477static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
7478 void *closure) {
7479 if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
7480}
7481
7482#endif /* UPB_DEBUG_REFS */
7483
7484
7485/* freeze() *******************************************************************/
7486
7487/* The freeze() operation is by far the most complicated part of this scheme.
7488 * We compute strongly-connected components and then mutate the graph such that
7489 * we preserve the invariants documented at the top of this file. And we must
7490 * handle out-of-memory errors gracefully (without leaving the graph
7491 * inconsistent), which adds to the fun. */
7492
7493/* The state used by the freeze operation (shared across many functions). */
7494typedef struct {
7495 int depth;
7496 int maxdepth;
7497 uint64_t index;
7498 /* Maps upb_refcounted* -> attributes (color, etc). attr layout varies by
7499 * color. */
7500 upb_inttable objattr;
7501 upb_inttable stack; /* stack of upb_refcounted* for Tarjan's algorithm. */
7502 upb_inttable groups; /* array of uint32_t*, malloc'd refcounts for new groups */
7503 upb_status *status;
7504 jmp_buf err;
7505} tarjan;
7506
7507static void release_ref2(const upb_refcounted *obj,
7508 const upb_refcounted *subobj,
7509 void *closure);
7510
7511/* Node attributes -----------------------------------------------------------*/
7512
7513/* After our analysis phase all nodes will be either GRAY or WHITE. */
7514
7515typedef enum {
7516 BLACK = 0, /* Object has not been seen. */
7517 GRAY, /* Object has been found via a refgroup but may not be reachable. */
7518 GREEN, /* Object is reachable and is currently on the Tarjan stack. */
7519 WHITE /* Object is reachable and has been assigned a group (SCC). */
7520} color_t;
7521
7522UPB_NORETURN static void err(tarjan *t) { longjmp(t->err, 1); }
7523UPB_NORETURN static void oom(tarjan *t) {
7524 upb_status_seterrmsg(t->status, "out of memory");
7525 err(t);
7526}
7527
7528static uint64_t trygetattr(const tarjan *t, const upb_refcounted *r) {
7529 upb_value v;
7530 return upb_inttable_lookupptr(&t->objattr, r, &v) ?
7531 upb_value_getuint64(v) : 0;
7532}
7533
7534static uint64_t getattr(const tarjan *t, const upb_refcounted *r) {
7535 upb_value v;
7536 bool found = upb_inttable_lookupptr(&t->objattr, r, &v);
7537 UPB_ASSERT(found);
7538 return upb_value_getuint64(v);
7539}
7540
7541static void setattr(tarjan *t, const upb_refcounted *r, uint64_t attr) {
7542 upb_inttable_removeptr(&t->objattr, r, NULL);
7543 upb_inttable_insertptr(&t->objattr, r, upb_value_uint64(attr));
7544}
7545
7546static color_t color(tarjan *t, const upb_refcounted *r) {
7547 return trygetattr(t, r) & 0x3; /* Color is always stored in the low 2 bits. */
7548}
7549
7550static void set_gray(tarjan *t, const upb_refcounted *r) {
7551 UPB_ASSERT(color(t, r) == BLACK);
7552 setattr(t, r, GRAY);
7553}
7554
7555/* Pushes an obj onto the Tarjan stack and sets it to GREEN. */
7556static void push(tarjan *t, const upb_refcounted *r) {
7557 UPB_ASSERT(color(t, r) == BLACK || color(t, r) == GRAY);
7558 /* This defines the attr layout for the GREEN state. "index" and "lowlink"
7559 * get 31 bits, which is plenty (limit of 2B objects frozen at a time). */
7560 setattr(t, r, GREEN | (t->index << 2) | (t->index << 33));
7561 if (++t->index == 0x80000000) {
7562 upb_status_seterrmsg(t->status, "too many objects to freeze");
7563 err(t);
7564 }
7565 upb_inttable_push(&t->stack, upb_value_ptr((void*)r));
7566}
7567
7568/* Pops an obj from the Tarjan stack and sets it to WHITE, with a ptr to its
7569 * SCC group. */
7570static upb_refcounted *pop(tarjan *t) {
7571 upb_refcounted *r = upb_value_getptr(upb_inttable_pop(&t->stack));
7572 UPB_ASSERT(color(t, r) == GREEN);
7573 /* This defines the attr layout for nodes in the WHITE state.
7574 * Top of group stack is [group, NULL]; we point at group. */
7575 setattr(t, r, WHITE | (upb_inttable_count(&t->groups) - 2) << 8);
7576 return r;
7577}
7578
7579static void tarjan_newgroup(tarjan *t) {
7580 uint32_t *group = upb_gmalloc(sizeof(*group));
7581 if (!group) oom(t);
7582 /* Push group and empty group leader (we'll fill in leader later). */
7583 if (!upb_inttable_push(&t->groups, upb_value_ptr(group)) ||
7584 !upb_inttable_push(&t->groups, upb_value_ptr(NULL))) {
7585 upb_gfree(group);
7586 oom(t);
7587 }
7588 *group = 0;
7589}
7590
7591static uint32_t idx(tarjan *t, const upb_refcounted *r) {
7592 UPB_ASSERT(color(t, r) == GREEN);
7593 return (getattr(t, r) >> 2) & 0x7FFFFFFF;
7594}
7595
7596static uint32_t lowlink(tarjan *t, const upb_refcounted *r) {
7597 if (color(t, r) == GREEN) {
7598 return getattr(t, r) >> 33;
7599 } else {
7600 return UINT32_MAX;
7601 }
7602}
7603
7604static void set_lowlink(tarjan *t, const upb_refcounted *r, uint32_t lowlink) {
7605 UPB_ASSERT(color(t, r) == GREEN);
7606 setattr(t, r, ((uint64_t)lowlink << 33) | (getattr(t, r) & 0x1FFFFFFFF));
7607}
7608
7609static uint32_t *group(tarjan *t, upb_refcounted *r) {
7610 uint64_t groupnum;
7611 upb_value v;
7612 bool found;
7613
7614 UPB_ASSERT(color(t, r) == WHITE);
7615 groupnum = getattr(t, r) >> 8;
7616 found = upb_inttable_lookup(&t->groups, groupnum, &v);
7617 UPB_ASSERT(found);
7618 return upb_value_getptr(v);
7619}
7620
7621/* If the group leader for this object's group has not previously been set,
7622 * the given object is assigned to be its leader. */
7623static upb_refcounted *groupleader(tarjan *t, upb_refcounted *r) {
7624 uint64_t leader_slot;
7625 upb_value v;
7626 bool found;
7627
7628 UPB_ASSERT(color(t, r) == WHITE);
7629 leader_slot = (getattr(t, r) >> 8) + 1;
7630 found = upb_inttable_lookup(&t->groups, leader_slot, &v);
7631 UPB_ASSERT(found);
7632 if (upb_value_getptr(v)) {
7633 return upb_value_getptr(v);
7634 } else {
7635 upb_inttable_remove(&t->groups, leader_slot, NULL);
7636 upb_inttable_insert(&t->groups, leader_slot, upb_value_ptr(r));
7637 return r;
7638 }
7639}
7640
7641
7642/* Tarjan's algorithm --------------------------------------------------------*/
7643
7644/* See:
7645 * http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm */
7646static void do_tarjan(const upb_refcounted *obj, tarjan *t);
7647
7648static void tarjan_visit(const upb_refcounted *obj,
7649 const upb_refcounted *subobj,
7650 void *closure) {
7651 tarjan *t = closure;
7652 if (++t->depth > t->maxdepth) {
7653 upb_status_seterrf(t->status, "graph too deep to freeze (%d)", t->maxdepth);
7654 err(t);
7655 } else if (subobj->is_frozen || color(t, subobj) == WHITE) {
7656 /* Do nothing: we don't want to visit or color already-frozen nodes,
7657 * and WHITE nodes have already been assigned a SCC. */
7658 } else if (color(t, subobj) < GREEN) {
7659 /* Subdef has not yet been visited; recurse on it. */
7660 do_tarjan(subobj, t);
7661 set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), lowlink(t, subobj)));
7662 } else if (color(t, subobj) == GREEN) {
7663 /* Subdef is in the stack and hence in the current SCC. */
7664 set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), idx(t, subobj)));
7665 }
7666 --t->depth;
7667}
7668
7669static void do_tarjan(const upb_refcounted *obj, tarjan *t) {
7670 if (color(t, obj) == BLACK) {
7671 /* We haven't seen this object's group; mark the whole group GRAY. */
7672 const upb_refcounted *o = obj;
7673 do { set_gray(t, o); } while ((o = o->next) != obj);
7674 }
7675
7676 push(t, obj);
7677 visit(obj, tarjan_visit, t);
7678 if (lowlink(t, obj) == idx(t, obj)) {
7679 tarjan_newgroup(t);
7680 while (pop(t) != obj)
7681 ;
7682 }
7683}
7684
7685
7686/* freeze() ------------------------------------------------------------------*/
7687
7688static void crossref(const upb_refcounted *r, const upb_refcounted *subobj,
7689 void *_t) {
7690 tarjan *t = _t;
7691 UPB_ASSERT(color(t, r) > BLACK);
7692 if (color(t, subobj) > BLACK && r->group != subobj->group) {
7693 /* Previously this ref was not reflected in subobj->group because they
7694 * were in the same group; now that they are split a ref must be taken. */
7695 refgroup(subobj->group);
7696 }
7697}
7698
7699static bool freeze(upb_refcounted *const*roots, int n, upb_status *s,
7700 int maxdepth) {
7701 volatile bool ret = false;
7702 int i;
7703 upb_inttable_iter iter;
7704
7705 /* We run in two passes so that we can allocate all memory before performing
7706 * any mutation of the input -- this allows us to leave the input unchanged
7707 * in the case of memory allocation failure. */
7708 tarjan t;
7709 t.index = 0;
7710 t.depth = 0;
7711 t.maxdepth = maxdepth;
7712 t.status = s;
7713 if (!upb_inttable_init(&t.objattr, UPB_CTYPE_UINT64)) goto err1;
7714 if (!upb_inttable_init(&t.stack, UPB_CTYPE_PTR)) goto err2;
7715 if (!upb_inttable_init(&t.groups, UPB_CTYPE_PTR)) goto err3;
7716 if (setjmp(t.err) != 0) goto err4;
7717
7718
7719 for (i = 0; i < n; i++) {
7720 if (color(&t, roots[i]) < GREEN) {
7721 do_tarjan(roots[i], &t);
7722 }
7723 }
7724
7725 /* If we've made it this far, no further errors are possible so it's safe to
7726 * mutate the objects without risk of leaving them in an inconsistent state. */
7727 ret = true;
7728
7729 /* The transformation that follows requires care. The preconditions are:
7730 * - all objects in attr map are WHITE or GRAY, and are in mutable groups
7731 * (groups of all mutable objs)
7732 * - no ref2(to, from) refs have incremented count(to) if both "to" and
7733 * "from" are in our attr map (this follows from invariants (2) and (3)) */
7734
7735 /* Pass 1: we remove WHITE objects from their mutable groups, and add them to
7736 * new groups according to the SCC's we computed. These new groups will
7737 * consist of only frozen objects. None will be immediately collectible,
7738 * because WHITE objects are by definition reachable from one of "roots",
7739 * which the caller must own refs on. */
7740 upb_inttable_begin(&iter, &t.objattr);
7741 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
7742 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
7743 /* Since removal from a singly-linked list requires access to the object's
7744 * predecessor, we consider obj->next instead of obj for moving. With the
7745 * while() loop we guarantee that we will visit every node's predecessor.
7746 * Proof:
7747 * 1. every node's predecessor is in our attr map.
7748 * 2. though the loop body may change a node's predecessor, it will only
7749 * change it to be the node we are currently operating on, so with a
7750 * while() loop we guarantee ourselves the chance to remove each node. */
7751 while (color(&t, obj->next) == WHITE &&
7752 group(&t, obj->next) != obj->next->group) {
7753 upb_refcounted *leader;
7754
7755 /* Remove from old group. */
7756 upb_refcounted *move = obj->next;
7757 if (obj == move) {
7758 /* Removing the last object from a group. */
7759 UPB_ASSERT(*obj->group == obj->individual_count);
7760 upb_gfree(obj->group);
7761 } else {
7762 obj->next = move->next;
7763 /* This may decrease to zero; we'll collect GRAY objects (if any) that
7764 * remain in the group in the third pass. */
7765 UPB_ASSERT(*move->group >= move->individual_count);
7766 *move->group -= move->individual_count;
7767 }
7768
7769 /* Add to new group. */
7770 leader = groupleader(&t, move);
7771 if (move == leader) {
7772 /* First object added to new group is its leader. */
7773 move->group = group(&t, move);
7774 move->next = move;
7775 *move->group = move->individual_count;
7776 } else {
7777 /* Group already has at least one object in it. */
7778 UPB_ASSERT(leader->group == group(&t, move));
7779 move->group = group(&t, move);
7780 move->next = leader->next;
7781 leader->next = move;
7782 *move->group += move->individual_count;
7783 }
7784
7785 move->is_frozen = true;
7786 }
7787 }
7788
7789 /* Pass 2: GRAY and WHITE objects "obj" with ref2(to, obj) references must
7790 * increment count(to) if group(obj) != group(to) (which could now be the
7791 * case if "to" was just frozen). */
7792 upb_inttable_begin(&iter, &t.objattr);
7793 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
7794 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
7795 visit(obj, crossref, &t);
7796 }
7797
7798 /* Pass 3: GRAY objects are collected if their group's refcount dropped to
7799 * zero when we removed its white nodes. This can happen if they had only
7800 * been kept alive by virtue of sharing a group with an object that was just
7801 * frozen.
7802 *
7803 * It is important that we do this last, since the GRAY object's free()
7804 * function could call unref2() on just-frozen objects, which will decrement
7805 * refs that were added in pass 2. */
7806 upb_inttable_begin(&iter, &t.objattr);
7807 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
7808 upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
7809 if (obj->group == NULL || *obj->group == 0) {
7810 if (obj->group) {
7811 upb_refcounted *o;
7812
7813 /* We eagerly free() the group's count (since we can't easily determine
7814 * the group's remaining size it's the easiest way to ensure it gets
7815 * done). */
7816 upb_gfree(obj->group);
7817
7818 /* Visit to release ref2's (done in a separate pass since release_ref2
7819 * depends on o->group being unmodified so it can test merged()). */
7820 o = obj;
7821 do { visit(o, release_ref2, NULL); } while ((o = o->next) != obj);
7822
7823 /* Mark "group" fields as NULL so we know to free the objects later in
7824 * this loop, but also don't try to delete the group twice. */
7825 o = obj;
7826 do { o->group = NULL; } while ((o = o->next) != obj);
7827 }
7828 freeobj(obj);
7829 }
7830 }
7831
7832err4:
7833 if (!ret) {
7834 upb_inttable_begin(&iter, &t.groups);
7835 for(; !upb_inttable_done(&iter); upb_inttable_next(&iter))
7836 upb_gfree(upb_value_getptr(upb_inttable_iter_value(&iter)));
7837 }
7838 upb_inttable_uninit(&t.groups);
7839err3:
7840 upb_inttable_uninit(&t.stack);
7841err2:
7842 upb_inttable_uninit(&t.objattr);
7843err1:
7844 return ret;
7845}
7846
7847
7848/* Misc internal functions ***************************************************/
7849
7850static bool merged(const upb_refcounted *r, const upb_refcounted *r2) {
7851 return r->group == r2->group;
7852}
7853
7854static void merge(upb_refcounted *r, upb_refcounted *from) {
7855 upb_refcounted *base;
7856 upb_refcounted *tmp;
7857
7858 if (merged(r, from)) return;
7859 *r->group += *from->group;
7860 upb_gfree(from->group);
7861 base = from;
7862
7863 /* Set all refcount pointers in the "from" chain to the merged refcount.
7864 *
7865 * TODO(haberman): this linear algorithm can result in an overall O(n^2) bound
7866 * if the user continuously extends a group by one object. Prevent this by
7867 * using one of the techniques in this paper:
7868 * http://bioinfo.ict.ac.cn/~dbu/AlgorithmCourses/Lectures/Union-Find-Tarjan.pdf */
7869 do { from->group = r->group; } while ((from = from->next) != base);
7870
7871 /* Merge the two circularly linked lists by swapping their next pointers. */
7872 tmp = r->next;
7873 r->next = base->next;
7874 base->next = tmp;
7875}
7876
7877static void unref(const upb_refcounted *r);
7878
7879static void release_ref2(const upb_refcounted *obj,
7880 const upb_refcounted *subobj,
7881 void *closure) {
7882 UPB_UNUSED(closure);
7883 untrack(subobj, obj, true);
7884 if (!merged(obj, subobj)) {
7885 UPB_ASSERT(subobj->is_frozen);
7886 unref(subobj);
7887 }
7888}
7889
7890static void unref(const upb_refcounted *r) {
7891 if (unrefgroup(r->group)) {
7892 const upb_refcounted *o;
7893
7894 upb_gfree(r->group);
7895
7896 /* In two passes, since release_ref2 needs a guarantee that any subobjs
7897 * are alive. */
7898 o = r;
7899 do { visit(o, release_ref2, NULL); } while((o = o->next) != r);
7900
7901 o = r;
7902 do {
7903 const upb_refcounted *next = o->next;
7904 UPB_ASSERT(o->is_frozen || o->individual_count == 0);
7905 freeobj((upb_refcounted*)o);
7906 o = next;
7907 } while(o != r);
7908 }
7909}
7910
7911static void freeobj(upb_refcounted *o) {
7912 trackfree(o);
7913 o->vtbl->free((upb_refcounted*)o);
7914}
7915
7916
7917/* Public interface ***********************************************************/
7918
7919bool upb_refcounted_init(upb_refcounted *r,
7920 const struct upb_refcounted_vtbl *vtbl,
7921 const void *owner) {
7922#ifndef NDEBUG
7923 /* Endianness check. This is unrelated to upb_refcounted, it's just a
7924 * convenient place to put the check that we can be assured will run for
7925 * basically every program using upb. */
7926 const int x = 1;
7927#ifdef UPB_BIG_ENDIAN
7928 UPB_ASSERT(*(char*)&x != 1);
7929#else
7930 UPB_ASSERT(*(char*)&x == 1);
7931#endif
7932#endif
7933
7934 r->next = r;
7935 r->vtbl = vtbl;
7936 r->individual_count = 0;
7937 r->is_frozen = false;
7938 r->group = upb_gmalloc(sizeof(*r->group));
7939 if (!r->group) return false;
7940 *r->group = 0;
7941 trackinit(r);
7942 upb_refcounted_ref(r, owner);
7943 return true;
7944}
7945
7946bool upb_refcounted_isfrozen(const upb_refcounted *r) {
7947 return r->is_frozen;
7948}
7949
7950void upb_refcounted_ref(const upb_refcounted *r, const void *owner) {
7951 track(r, owner, false);
7952 if (!r->is_frozen)
7953 ((upb_refcounted*)r)->individual_count++;
7954 refgroup(r->group);
7955}
7956
7957void upb_refcounted_unref(const upb_refcounted *r, const void *owner) {
7958 untrack(r, owner, false);
7959 if (!r->is_frozen)
7960 ((upb_refcounted*)r)->individual_count--;
7961 unref(r);
7962}
7963
7964void upb_refcounted_ref2(const upb_refcounted *r, upb_refcounted *from) {
7965 UPB_ASSERT(!from->is_frozen); /* Non-const pointer implies this. */
7966 track(r, from, true);
7967 if (r->is_frozen) {
7968 refgroup(r->group);
7969 } else {
7970 merge((upb_refcounted*)r, from);
7971 }
7972}
7973
7974void upb_refcounted_unref2(const upb_refcounted *r, upb_refcounted *from) {
7975 UPB_ASSERT(!from->is_frozen); /* Non-const pointer implies this. */
7976 untrack(r, from, true);
7977 if (r->is_frozen) {
7978 unref(r);
7979 } else {
7980 UPB_ASSERT(merged(r, from));
7981 }
7982}
7983
7984void upb_refcounted_donateref(
7985 const upb_refcounted *r, const void *from, const void *to) {
7986 UPB_ASSERT(from != to);
7987 if (to != NULL)
7988 upb_refcounted_ref(r, to);
7989 if (from != NULL)
7990 upb_refcounted_unref(r, from);
7991}
7992
7993void upb_refcounted_checkref(const upb_refcounted *r, const void *owner) {
7994 checkref(r, owner, false);
7995}
7996
7997bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
7998 int maxdepth) {
7999 int i;
8000 bool ret;
8001 for (i = 0; i < n; i++) {
8002 UPB_ASSERT(!roots[i]->is_frozen);
8003 }
8004 ret = freeze(roots, n, s, maxdepth);
8005 UPB_ASSERT(!s || ret == upb_ok(s));
8006 return ret;
8007}
8008
8009
8010bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink *sink) {
8011 void *subc;
8012 bool ret;
8013 upb_bufhandle handle;
8014 upb_bufhandle_init(&handle);
8015 upb_bufhandle_setbuf(&handle, buf, 0);
8016 ret = upb_bytessink_start(sink, len, &subc);
8017 if (ret && len != 0) {
8018 ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len);
8019 }
8020 if (ret) {
8021 ret = upb_bytessink_end(sink);
8022 }
8023 upb_bufhandle_uninit(&handle);
8024 return ret;
8025}
8026
8027struct upb_bufsink {
8028 upb_byteshandler handler;
8029 upb_bytessink sink;
8030 upb_env *env;
8031 char *ptr;
8032 size_t len, size;
8033};
8034
8035static void *upb_bufsink_start(void *_sink, const void *hd, size_t size_hint) {
8036 upb_bufsink *sink = _sink;
8037 UPB_UNUSED(hd);
8038 UPB_UNUSED(size_hint);
8039 sink->len = 0;
8040 return sink;
8041}
8042
8043static size_t upb_bufsink_string(void *_sink, const void *hd, const char *ptr,
8044 size_t len, const upb_bufhandle *handle) {
8045 upb_bufsink *sink = _sink;
8046 size_t new_size = sink->size;
8047
8048 UPB_ASSERT(new_size > 0);
8049 UPB_UNUSED(hd);
8050 UPB_UNUSED(handle);
8051
8052 while (sink->len + len > new_size) {
8053 new_size *= 2;
8054 }
8055
8056 if (new_size != sink->size) {
8057 sink->ptr = upb_env_realloc(sink->env, sink->ptr, sink->size, new_size);
8058 sink->size = new_size;
8059 }
8060
8061 memcpy(sink->ptr + sink->len, ptr, len);
8062 sink->len += len;
8063
8064 return len;
8065}
8066
8067upb_bufsink *upb_bufsink_new(upb_env *env) {
8068 upb_bufsink *sink = upb_env_malloc(env, sizeof(upb_bufsink));
8069 upb_byteshandler_init(&sink->handler);
8070 upb_byteshandler_setstartstr(&sink->handler, upb_bufsink_start, NULL);
8071 upb_byteshandler_setstring(&sink->handler, upb_bufsink_string, NULL);
8072
8073 upb_bytessink_reset(&sink->sink, &sink->handler, sink);
8074
8075 sink->env = env;
8076 sink->size = 32;
8077 sink->ptr = upb_env_malloc(env, sink->size);
8078 sink->len = 0;
8079
8080 return sink;
8081}
8082
8083void upb_bufsink_free(upb_bufsink *sink) {
8084 upb_env_free(sink->env, sink->ptr);
8085 upb_env_free(sink->env, sink);
8086}
8087
8088upb_bytessink *upb_bufsink_sink(upb_bufsink *sink) {
8089 return &sink->sink;
8090}
8091
8092const char *upb_bufsink_getdata(const upb_bufsink *sink, size_t *len) {
8093 *len = sink->len;
8094 return sink->ptr;
8095}
8096/*
8097** upb_table Implementation
8098**
8099** Implementation is heavily inspired by Lua's ltable.c.
8100*/
8101
8102
8103#include <string.h>
8104
8105#define UPB_MAXARRSIZE 16 /* 64k. */
8106
8107/* From Chromium. */
8108#define ARRAY_SIZE(x) \
8109 ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
8110
8111static void upb_check_alloc(upb_table *t, upb_alloc *a) {
8112 UPB_UNUSED(t);
8113 UPB_UNUSED(a);
8114 UPB_ASSERT_DEBUGVAR(t->alloc == a);
8115}
8116
8117static const double MAX_LOAD = 0.85;
8118
8119/* The minimum utilization of the array part of a mixed hash/array table. This
8120 * is a speed/memory-usage tradeoff (though it's not straightforward because of
8121 * cache effects). The lower this is, the more memory we'll use. */
8122static const double MIN_DENSITY = 0.1;
8123
8124bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
8125
8126int log2ceil(uint64_t v) {
8127 int ret = 0;
8128 bool pow2 = is_pow2(v);
8129 while (v >>= 1) ret++;
8130 ret = pow2 ? ret : ret + 1; /* Ceiling. */
8131 return UPB_MIN(UPB_MAXARRSIZE, ret);
8132}
8133
8134char *upb_strdup(const char *s, upb_alloc *a) {
8135 return upb_strdup2(s, strlen(s), a);
8136}
8137
8138char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
8139 size_t n;
8140 char *p;
8141
8142 /* Prevent overflow errors. */
8143 if (len == SIZE_MAX) return NULL;
8144 /* Always null-terminate, even if binary data; but don't rely on the input to
8145 * have a null-terminating byte since it may be a raw binary buffer. */
8146 n = len + 1;
8147 p = upb_malloc(a, n);
8148 if (p) {
8149 memcpy(p, s, len);
8150 p[len] = 0;
8151 }
8152 return p;
8153}
8154
8155/* A type to represent the lookup key of either a strtable or an inttable. */
8156typedef union {
8157 uintptr_t num;
8158 struct {
8159 const char *str;
8160 size_t len;
8161 } str;
8162} lookupkey_t;
8163
8164static lookupkey_t strkey2(const char *str, size_t len) {
8165 lookupkey_t k;
8166 k.str.str = str;
8167 k.str.len = len;
8168 return k;
8169}
8170
8171static lookupkey_t intkey(uintptr_t key) {
8172 lookupkey_t k;
8173 k.num = key;
8174 return k;
8175}
8176
8177typedef uint32_t hashfunc_t(upb_tabkey key);
8178typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
8179
8180/* Base table (shared code) ***************************************************/
8181
8182/* For when we need to cast away const. */
8183static upb_tabent *mutable_entries(upb_table *t) {
8184 return (upb_tabent*)t->entries;
8185}
8186
8187static bool isfull(upb_table *t) {
8188 if (upb_table_size(t) == 0) {
8189 return true;
8190 } else {
8191 return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
8192 }
8193}
8194
8195static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
8196 upb_alloc *a) {
8197 size_t bytes;
8198
8199 t->count = 0;
8200 t->ctype = ctype;
8201 t->size_lg2 = size_lg2;
8202 t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
8203#ifndef NDEBUG
8204 t->alloc = a;
8205#endif
8206 bytes = upb_table_size(t) * sizeof(upb_tabent);
8207 if (bytes > 0) {
8208 t->entries = upb_malloc(a, bytes);
8209 if (!t->entries) return false;
8210 memset(mutable_entries(t), 0, bytes);
8211 } else {
8212 t->entries = NULL;
8213 }
8214 return true;
8215}
8216
8217static void uninit(upb_table *t, upb_alloc *a) {
8218 upb_check_alloc(t, a);
8219 upb_free(a, mutable_entries(t));
8220}
8221
8222static upb_tabent *emptyent(upb_table *t) {
8223 upb_tabent *e = mutable_entries(t) + upb_table_size(t);
8224 while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); }
8225}
8226
8227static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
8228 return (upb_tabent*)upb_getentry(t, hash);
8229}
8230
8231static const upb_tabent *findentry(const upb_table *t, lookupkey_t key,
8232 uint32_t hash, eqlfunc_t *eql) {
8233 const upb_tabent *e;
8234
8235 if (t->size_lg2 == 0) return NULL;
8236 e = upb_getentry(t, hash);
8237 if (upb_tabent_isempty(e)) return NULL;
8238 while (1) {
8239 if (eql(e->key, key)) return e;
8240 if ((e = e->next) == NULL) return NULL;
8241 }
8242}
8243
8244static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key,
8245 uint32_t hash, eqlfunc_t *eql) {
8246 return (upb_tabent*)findentry(t, key, hash, eql);
8247}
8248
8249static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
8250 uint32_t hash, eqlfunc_t *eql) {
8251 const upb_tabent *e = findentry(t, key, hash, eql);
8252 if (e) {
8253 if (v) {
8254 _upb_value_setval(v, e->val.val, t->ctype);
8255 }
8256 return true;
8257 } else {
8258 return false;
8259 }
8260}
8261
8262/* The given key must not already exist in the table. */
8263static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
8264 upb_value val, uint32_t hash,
8265 hashfunc_t *hashfunc, eqlfunc_t *eql) {
8266 upb_tabent *mainpos_e;
8267 upb_tabent *our_e;
8268
8269 UPB_ASSERT(findentry(t, key, hash, eql) == NULL);
8270 UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype);
8271
8272 t->count++;
8273 mainpos_e = getentry_mutable(t, hash);
8274 our_e = mainpos_e;
8275
8276 if (upb_tabent_isempty(mainpos_e)) {
8277 /* Our main position is empty; use it. */
8278 our_e->next = NULL;
8279 } else {
8280 /* Collision. */
8281 upb_tabent *new_e = emptyent(t);
8282 /* Head of collider's chain. */
8283 upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
8284 if (chain == mainpos_e) {
8285 /* Existing ent is in its main posisiton (it has the same hash as us, and
8286 * is the head of our chain). Insert to new ent and append to this chain. */
8287 new_e->next = mainpos_e->next;
8288 mainpos_e->next = new_e;
8289 our_e = new_e;
8290 } else {
8291 /* Existing ent is not in its main position (it is a node in some other
8292 * chain). This implies that no existing ent in the table has our hash.
8293 * Evict it (updating its chain) and use its ent for head of our chain. */
8294 *new_e = *mainpos_e; /* copies next. */
8295 while (chain->next != mainpos_e) {
8296 chain = (upb_tabent*)chain->next;
8297 UPB_ASSERT(chain);
8298 }
8299 chain->next = new_e;
8300 our_e = mainpos_e;
8301 our_e->next = NULL;
8302 }
8303 }
8304 our_e->key = tabkey;
8305 our_e->val.val = val.val;
8306 UPB_ASSERT(findentry(t, key, hash, eql) == our_e);
8307}
8308
8309static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
8310 upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
8311 upb_tabent *chain = getentry_mutable(t, hash);
8312 if (upb_tabent_isempty(chain)) return false;
8313 if (eql(chain->key, key)) {
8314 /* Element to remove is at the head of its chain. */
8315 t->count--;
8316 if (val) _upb_value_setval(val, chain->val.val, t->ctype);
8317 if (removed) *removed = chain->key;
8318 if (chain->next) {
8319 upb_tabent *move = (upb_tabent*)chain->next;
8320 *chain = *move;
8321 move->key = 0; /* Make the slot empty. */
8322 } else {
8323 chain->key = 0; /* Make the slot empty. */
8324 }
8325 return true;
8326 } else {
8327 /* Element to remove is either in a non-head position or not in the
8328 * table. */
8329 while (chain->next && !eql(chain->next->key, key)) {
8330 chain = (upb_tabent*)chain->next;
8331 }
8332 if (chain->next) {
8333 /* Found element to remove. */
8334 upb_tabent *rm = (upb_tabent*)chain->next;
8335 t->count--;
8336 if (val) _upb_value_setval(val, chain->next->val.val, t->ctype);
8337 if (removed) *removed = rm->key;
8338 rm->key = 0; /* Make the slot empty. */
8339 chain->next = rm->next;
8340 return true;
8341 } else {
8342 /* Element to remove is not in the table. */
8343 return false;
8344 }
8345 }
8346}
8347
8348static size_t next(const upb_table *t, size_t i) {
8349 do {
8350 if (++i >= upb_table_size(t))
8351 return SIZE_MAX;
8352 } while(upb_tabent_isempty(&t->entries[i]));
8353
8354 return i;
8355}
8356
8357static size_t begin(const upb_table *t) {
8358 return next(t, -1);
8359}
8360
8361
8362/* upb_strtable ***************************************************************/
8363
8364/* A simple "subclass" of upb_table that only adds a hash function for strings. */
8365
8366static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
8367 char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
8368 if (str == NULL) return 0;
8369 memcpy(str, &k2.str.len, sizeof(uint32_t));
8370 memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
8371 return (uintptr_t)str;
8372}
8373
8374static uint32_t strhash(upb_tabkey key) {
8375 uint32_t len;
8376 char *str = upb_tabstr(key, &len);
8377 return MurmurHash2(str, len, 0);
8378}
8379
8380static bool streql(upb_tabkey k1, lookupkey_t k2) {
8381 uint32_t len;
8382 char *str = upb_tabstr(k1, &len);
8383 return len == k2.str.len && memcmp(str, k2.str.str, len) == 0;
8384}
8385
8386bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
8387 return init(&t->t, ctype, 2, a);
8388}
8389
8390void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
8391 size_t i;
8392 for (i = 0; i < upb_table_size(&t->t); i++)
8393 upb_free(a, (void*)t->t.entries[i].key);
8394 uninit(&t->t, a);
8395}
8396
8397bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
8398 upb_strtable new_table;
8399 upb_strtable_iter i;
8400
8401 upb_check_alloc(&t->t, a);
8402
8403 if (!init(&new_table.t, t->t.ctype, size_lg2, a))
8404 return false;
8405 upb_strtable_begin(&i, t);
8406 for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
8407 upb_strtable_insert3(
8408 &new_table,
8409 upb_strtable_iter_key(&i),
8410 upb_strtable_iter_keylength(&i),
8411 upb_strtable_iter_value(&i),
8412 a);
8413 }
8414 upb_strtable_uninit2(t, a);
8415 *t = new_table;
8416 return true;
8417}
8418
8419bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
8420 upb_value v, upb_alloc *a) {
8421 lookupkey_t key;
8422 upb_tabkey tabkey;
8423 uint32_t hash;
8424
8425 upb_check_alloc(&t->t, a);
8426
8427 if (isfull(&t->t)) {
8428 /* Need to resize. New table of double the size, add old elements to it. */
8429 if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
8430 return false;
8431 }
8432 }
8433
8434 key = strkey2(k, len);
8435 tabkey = strcopy(key, a);
8436 if (tabkey == 0) return false;
8437
8438 hash = MurmurHash2(key.str.str, key.str.len, 0);
8439 insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
8440 return true;
8441}
8442
8443bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
8444 upb_value *v) {
8445 uint32_t hash = MurmurHash2(key, len, 0);
8446 return lookup(&t->t, strkey2(key, len), v, hash, &streql);
8447}
8448
8449bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
8450 upb_value *val, upb_alloc *alloc) {
8451 uint32_t hash = MurmurHash2(key, len, 0);
8452 upb_tabkey tabkey;
8453 if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
8454 upb_free(alloc, (void*)tabkey);
8455 return true;
8456 } else {
8457 return false;
8458 }
8459}
8460
8461/* Iteration */
8462
8463static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
8464 return &i->t->t.entries[i->index];
8465}
8466
8467void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
8468 i->t = t;
8469 i->index = begin(&t->t);
8470}
8471
8472void upb_strtable_next(upb_strtable_iter *i) {
8473 i->index = next(&i->t->t, i->index);
8474}
8475
8476bool upb_strtable_done(const upb_strtable_iter *i) {
8477 return i->index >= upb_table_size(&i->t->t) ||
8478 upb_tabent_isempty(str_tabent(i));
8479}
8480
8481const char *upb_strtable_iter_key(const upb_strtable_iter *i) {
8482 UPB_ASSERT(!upb_strtable_done(i));
8483 return upb_tabstr(str_tabent(i)->key, NULL);
8484}
8485
8486size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) {
8487 uint32_t len;
8488 UPB_ASSERT(!upb_strtable_done(i));
8489 upb_tabstr(str_tabent(i)->key, &len);
8490 return len;
8491}
8492
8493upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
8494 UPB_ASSERT(!upb_strtable_done(i));
8495 return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
8496}
8497
8498void upb_strtable_iter_setdone(upb_strtable_iter *i) {
8499 i->index = SIZE_MAX;
8500}
8501
8502bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
8503 const upb_strtable_iter *i2) {
8504 if (upb_strtable_done(i1) && upb_strtable_done(i2))
8505 return true;
8506 return i1->t == i2->t && i1->index == i2->index;
8507}
8508
8509
8510/* upb_inttable ***************************************************************/
8511
8512/* For inttables we use a hybrid structure where small keys are kept in an
8513 * array and large keys are put in the hash table. */
8514
8515static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
8516
8517static bool inteql(upb_tabkey k1, lookupkey_t k2) {
8518 return k1 == k2.num;
8519}
8520
8521static upb_tabval *mutable_array(upb_inttable *t) {
8522 return (upb_tabval*)t->array;
8523}
8524
8525static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
8526 if (key < t->array_size) {
8527 return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
8528 } else {
8529 upb_tabent *e =
8530 findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
8531 return e ? &e->val : NULL;
8532 }
8533}
8534
8535static const upb_tabval *inttable_val_const(const upb_inttable *t,
8536 uintptr_t key) {
8537 return inttable_val((upb_inttable*)t, key);
8538}
8539
8540size_t upb_inttable_count(const upb_inttable *t) {
8541 return t->t.count + t->array_count;
8542}
8543
8544static void check(upb_inttable *t) {
8545 UPB_UNUSED(t);
8546#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
8547 {
8548 /* This check is very expensive (makes inserts/deletes O(N)). */
8549 size_t count = 0;
8550 upb_inttable_iter i;
8551 upb_inttable_begin(&i, t);
8552 for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
8553 UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
8554 }
8555 UPB_ASSERT(count == upb_inttable_count(t));
8556 }
8557#endif
8558}
8559
8560bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
8561 size_t asize, int hsize_lg2, upb_alloc *a) {
8562 size_t array_bytes;
8563
8564 if (!init(&t->t, ctype, hsize_lg2, a)) return false;
8565 /* Always make the array part at least 1 long, so that we know key 0
8566 * won't be in the hash part, which simplifies things. */
8567 t->array_size = UPB_MAX(1, asize);
8568 t->array_count = 0;
8569 array_bytes = t->array_size * sizeof(upb_value);
8570 t->array = upb_malloc(a, array_bytes);
8571 if (!t->array) {
8572 uninit(&t->t, a);
8573 return false;
8574 }
8575 memset(mutable_array(t), 0xff, array_bytes);
8576 check(t);
8577 return true;
8578}
8579
8580bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
8581 return upb_inttable_sizedinit(t, ctype, 0, 4, a);
8582}
8583
8584void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
8585 uninit(&t->t, a);
8586 upb_free(a, mutable_array(t));
8587}
8588
8589bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
8590 upb_alloc *a) {
8591 upb_tabval tabval;
8592 tabval.val = val.val;
8593 UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
8594
8595 upb_check_alloc(&t->t, a);
8596
8597 if (key < t->array_size) {
8598 UPB_ASSERT(!upb_arrhas(t->array[key]));
8599 t->array_count++;
8600 mutable_array(t)[key].val = val.val;
8601 } else {
8602 if (isfull(&t->t)) {
8603 /* Need to resize the hash part, but we re-use the array part. */
8604 size_t i;
8605 upb_table new_table;
8606
8607 if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
8608 return false;
8609 }
8610
8611 for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
8612 const upb_tabent *e = &t->t.entries[i];
8613 uint32_t hash;
8614 upb_value v;
8615
8616 _upb_value_setval(&v, e->val.val, t->t.ctype);
8617 hash = upb_inthash(e->key);
8618 insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
8619 }
8620
8621 UPB_ASSERT(t->t.count == new_table.count);
8622
8623 uninit(&t->t, a);
8624 t->t = new_table;
8625 }
8626 insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
8627 }
8628 check(t);
8629 return true;
8630}
8631
8632bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
8633 const upb_tabval *table_v = inttable_val_const(t, key);
8634 if (!table_v) return false;
8635 if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
8636 return true;
8637}
8638
8639bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) {
8640 upb_tabval *table_v = inttable_val(t, key);
8641 if (!table_v) return false;
8642 table_v->val = val.val;
8643 return true;
8644}
8645
8646bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
8647 bool success;
8648 if (key < t->array_size) {
8649 if (upb_arrhas(t->array[key])) {
8650 upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
8651 t->array_count--;
8652 if (val) {
8653 _upb_value_setval(val, t->array[key].val, t->t.ctype);
8654 }
8655 mutable_array(t)[key] = empty;
8656 success = true;
8657 } else {
8658 success = false;
8659 }
8660 } else {
8661 success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql);
8662 }
8663 check(t);
8664 return success;
8665}
8666
8667bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
8668 upb_check_alloc(&t->t, a);
8669 return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
8670}
8671
8672upb_value upb_inttable_pop(upb_inttable *t) {
8673 upb_value val;
8674 bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val);
8675 UPB_ASSERT(ok);
8676 return val;
8677}
8678
8679bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
8680 upb_alloc *a) {
8681 upb_check_alloc(&t->t, a);
8682 return upb_inttable_insert2(t, (uintptr_t)key, val, a);
8683}
8684
8685bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
8686 upb_value *v) {
8687 return upb_inttable_lookup(t, (uintptr_t)key, v);
8688}
8689
8690bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
8691 return upb_inttable_remove(t, (uintptr_t)key, val);
8692}
8693
8694void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
8695 /* A power-of-two histogram of the table keys. */
8696 size_t counts[UPB_MAXARRSIZE + 1] = {0};
8697
8698 /* The max key in each bucket. */
8699 uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
8700
8701 upb_inttable_iter i;
8702 size_t arr_count;
8703 int size_lg2;
8704 upb_inttable new_t;
8705
8706 upb_check_alloc(&t->t, a);
8707
8708 upb_inttable_begin(&i, t);
8709 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
8710 uintptr_t key = upb_inttable_iter_key(&i);
8711 int bucket = log2ceil(key);
8712 max[bucket] = UPB_MAX(max[bucket], key);
8713 counts[bucket]++;
8714 }
8715
8716 /* Find the largest power of two that satisfies the MIN_DENSITY
8717 * definition (while actually having some keys). */
8718 arr_count = upb_inttable_count(t);
8719
8720 for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
8721 if (counts[size_lg2] == 0) {
8722 /* We can halve again without losing any entries. */
8723 continue;
8724 } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
8725 break;
8726 }
8727
8728 arr_count -= counts[size_lg2];
8729 }
8730
8731 UPB_ASSERT(arr_count <= upb_inttable_count(t));
8732
8733 {
8734 /* Insert all elements into new, perfectly-sized table. */
8735 size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
8736 size_t hash_count = upb_inttable_count(t) - arr_count;
8737 size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
8738 size_t hashsize_lg2 = log2ceil(hash_size);
8739
8740 upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
8741 upb_inttable_begin(&i, t);
8742 for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
8743 uintptr_t k = upb_inttable_iter_key(&i);
8744 upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
8745 }
8746 UPB_ASSERT(new_t.array_size == arr_size);
8747 UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
8748 }
8749 upb_inttable_uninit2(t, a);
8750 *t = new_t;
8751}
8752
8753/* Iteration. */
8754
8755static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
8756 UPB_ASSERT(!i->array_part);
8757 return &i->t->t.entries[i->index];
8758}
8759
8760static upb_tabval int_arrent(const upb_inttable_iter *i) {
8761 UPB_ASSERT(i->array_part);
8762 return i->t->array[i->index];
8763}
8764
8765void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
8766 i->t = t;
8767 i->index = -1;
8768 i->array_part = true;
8769 upb_inttable_next(i);
8770}
8771
8772void upb_inttable_next(upb_inttable_iter *iter) {
8773 const upb_inttable *t = iter->t;
8774 if (iter->array_part) {
8775 while (++iter->index < t->array_size) {
8776 if (upb_arrhas(int_arrent(iter))) {
8777 return;
8778 }
8779 }
8780 iter->array_part = false;
8781 iter->index = begin(&t->t);
8782 } else {
8783 iter->index = next(&t->t, iter->index);
8784 }
8785}
8786
8787bool upb_inttable_done(const upb_inttable_iter *i) {
8788 if (i->array_part) {
8789 return i->index >= i->t->array_size ||
8790 !upb_arrhas(int_arrent(i));
8791 } else {
8792 return i->index >= upb_table_size(&i->t->t) ||
8793 upb_tabent_isempty(int_tabent(i));
8794 }
8795}
8796
8797uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
8798 UPB_ASSERT(!upb_inttable_done(i));
8799 return i->array_part ? i->index : int_tabent(i)->key;
8800}
8801
8802upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
8803 UPB_ASSERT(!upb_inttable_done(i));
8804 return _upb_value_val(
8805 i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
8806 i->t->t.ctype);
8807}
8808
8809void upb_inttable_iter_setdone(upb_inttable_iter *i) {
8810 i->index = SIZE_MAX;
8811 i->array_part = false;
8812}
8813
8814bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
8815 const upb_inttable_iter *i2) {
8816 if (upb_inttable_done(i1) && upb_inttable_done(i2))
8817 return true;
8818 return i1->t == i2->t && i1->index == i2->index &&
8819 i1->array_part == i2->array_part;
8820}
8821
8822#ifdef UPB_UNALIGNED_READS_OK
8823/* -----------------------------------------------------------------------------
8824 * MurmurHash2, by Austin Appleby (released as public domain).
8825 * Reformatted and C99-ified by Joshua Haberman.
8826 * Note - This code makes a few assumptions about how your machine behaves -
8827 * 1. We can read a 4-byte value from any address without crashing
8828 * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
8829 * And it has a few limitations -
8830 * 1. It will not work incrementally.
8831 * 2. It will not produce the same results on little-endian and big-endian
8832 * machines. */
8833uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed) {
8834 /* 'm' and 'r' are mixing constants generated offline.
8835 * They're not really 'magic', they just happen to work well. */
8836 const uint32_t m = 0x5bd1e995;
8837 const int32_t r = 24;
8838
8839 /* Initialize the hash to a 'random' value */
8840 uint32_t h = seed ^ len;
8841
8842 /* Mix 4 bytes at a time into the hash */
8843 const uint8_t * data = (const uint8_t *)key;
8844 while(len >= 4) {
8845 uint32_t k = *(uint32_t *)data;
8846
8847 k *= m;
8848 k ^= k >> r;
8849 k *= m;
8850
8851 h *= m;
8852 h ^= k;
8853
8854 data += 4;
8855 len -= 4;
8856 }
8857
8858 /* Handle the last few bytes of the input array */
8859 switch(len) {
8860 case 3: h ^= data[2] << 16;
8861 case 2: h ^= data[1] << 8;
8862 case 1: h ^= data[0]; h *= m;
8863 };
8864
8865 /* Do a few final mixes of the hash to ensure the last few
8866 * bytes are well-incorporated. */
8867 h ^= h >> 13;
8868 h *= m;
8869 h ^= h >> 15;
8870
8871 return h;
8872}
8873
8874#else /* !UPB_UNALIGNED_READS_OK */
8875
8876/* -----------------------------------------------------------------------------
8877 * MurmurHashAligned2, by Austin Appleby
8878 * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
8879 * on certain platforms.
8880 * Performance will be lower than MurmurHash2 */
8881
8882#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
8883
8884uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) {
8885 const uint32_t m = 0x5bd1e995;
8886 const int32_t r = 24;
8887 const uint8_t * data = (const uint8_t *)key;
8888 uint32_t h = seed ^ len;
8889 uint8_t align = (uintptr_t)data & 3;
8890
8891 if(align && (len >= 4)) {
8892 /* Pre-load the temp registers */
8893 uint32_t t = 0, d = 0;
8894 int32_t sl;
8895 int32_t sr;
8896
8897 switch(align) {
8898 case 1: t |= data[2] << 16;
8899 case 2: t |= data[1] << 8;
8900 case 3: t |= data[0];
8901 }
8902
8903 t <<= (8 * align);
8904
8905 data += 4-align;
8906 len -= 4-align;
8907
8908 sl = 8 * (4-align);
8909 sr = 8 * align;
8910
8911 /* Mix */
8912
8913 while(len >= 4) {
8914 uint32_t k;
8915
8916 d = *(uint32_t *)data;
8917 t = (t >> sr) | (d << sl);
8918
8919 k = t;
8920
8921 MIX(h,k,m);
8922
8923 t = d;
8924
8925 data += 4;
8926 len -= 4;
8927 }
8928
8929 /* Handle leftover data in temp registers */
8930
8931 d = 0;
8932
8933 if(len >= align) {
8934 uint32_t k;
8935
8936 switch(align) {
8937 case 3: d |= data[2] << 16;
8938 case 2: d |= data[1] << 8;
8939 case 1: d |= data[0];
8940 }
8941
8942 k = (t >> sr) | (d << sl);
8943 MIX(h,k,m);
8944
8945 data += align;
8946 len -= align;
8947
8948 /* ----------
8949 * Handle tail bytes */
8950
8951 switch(len) {
8952 case 3: h ^= data[2] << 16;
8953 case 2: h ^= data[1] << 8;
8954 case 1: h ^= data[0]; h *= m;
8955 };
8956 } else {
8957 switch(len) {
8958 case 3: d |= data[2] << 16;
8959 case 2: d |= data[1] << 8;
8960 case 1: d |= data[0];
8961 case 0: h ^= (t >> sr) | (d << sl); h *= m;
8962 }
8963 }
8964
8965 h ^= h >> 13;
8966 h *= m;
8967 h ^= h >> 15;
8968
8969 return h;
8970 } else {
8971 while(len >= 4) {
8972 uint32_t k = *(uint32_t *)data;
8973
8974 MIX(h,k,m);
8975
8976 data += 4;
8977 len -= 4;
8978 }
8979
8980 /* ----------
8981 * Handle tail bytes */
8982
8983 switch(len) {
8984 case 3: h ^= data[2] << 16;
8985 case 2: h ^= data[1] << 8;
8986 case 1: h ^= data[0]; h *= m;
8987 };
8988
8989 h ^= h >> 13;
8990 h *= m;
8991 h ^= h >> 15;
8992
8993 return h;
8994 }
8995}
8996#undef MIX
8997
8998#endif /* UPB_UNALIGNED_READS_OK */
8999
9000#include <errno.h>
9001#include <stdarg.h>
9002#include <stddef.h>
9003#include <stdint.h>
9004#include <stdio.h>
9005#include <stdlib.h>
9006#include <string.h>
9007
9008bool upb_dumptostderr(void *closure, const upb_status* status) {
9009 UPB_UNUSED(closure);
9010 fprintf(stderr, "%s\n", upb_status_errmsg(status));
9011 return false;
9012}
9013
9014/* Guarantee null-termination and provide ellipsis truncation.
9015 * It may be tempting to "optimize" this by initializing these final
9016 * four bytes up-front and then being careful never to overwrite them,
9017 * this is safer and simpler. */
9018static void nullz(upb_status *status) {
9019 const char *ellipsis = "...";
9020 size_t len = strlen(ellipsis);
9021 UPB_ASSERT(sizeof(status->msg) > len);
9022 memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
9023}
9024
9025
9026/* upb_upberr *****************************************************************/
9027
9028upb_errorspace upb_upberr = {"upb error"};
9029
9030void upb_upberr_setoom(upb_status *status) {
9031 status->error_space_ = &upb_upberr;
9032 upb_status_seterrmsg(status, "Out of memory");
9033}
9034
9035
9036/* upb_status *****************************************************************/
9037
9038void upb_status_clear(upb_status *status) {
9039 if (!status) return;
9040 status->ok_ = true;
9041 status->code_ = 0;
9042 status->msg[0] = '\0';
9043}
9044
9045bool upb_ok(const upb_status *status) { return status->ok_; }
9046
9047upb_errorspace *upb_status_errspace(const upb_status *status) {
9048 return status->error_space_;
9049}
9050
9051int upb_status_errcode(const upb_status *status) { return status->code_; }
9052
9053const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
9054
9055void upb_status_seterrmsg(upb_status *status, const char *msg) {
9056 if (!status) return;
9057 status->ok_ = false;
9058 strncpy(status->msg, msg, sizeof(status->msg));
9059 nullz(status);
9060}
9061
9062void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
9063 va_list args;
9064 va_start(args, fmt);
9065 upb_status_vseterrf(status, fmt, args);
9066 va_end(args);
9067}
9068
9069void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
9070 if (!status) return;
9071 status->ok_ = false;
9072 _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
9073 nullz(status);
9074}
9075
9076void upb_status_copy(upb_status *to, const upb_status *from) {
9077 if (!to) return;
9078 *to = *from;
9079}
9080
9081
9082/* upb_alloc ******************************************************************/
9083
9084static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
9085 size_t size) {
9086 UPB_UNUSED(alloc);
9087 UPB_UNUSED(oldsize);
9088 if (size == 0) {
9089 free(ptr);
9090 return NULL;
9091 } else {
9092 return realloc(ptr, size);
9093 }
9094}
9095
9096upb_alloc upb_alloc_global = {&upb_global_allocfunc};
9097
9098
9099/* upb_arena ******************************************************************/
9100
9101/* Be conservative and choose 16 in case anyone is using SSE. */
9102static const size_t maxalign = 16;
9103
9104static size_t align_up_max(size_t size) {
9105 return ((size + maxalign - 1) / maxalign) * maxalign;
9106}
9107
9108typedef struct mem_block {
9109 struct mem_block *next;
9110 size_t size;
9111 size_t used;
9112 bool owned;
9113 /* Data follows. */
9114} mem_block;
9115
9116typedef struct cleanup_ent {
9117 struct cleanup_ent *next;
9118 upb_cleanup_func *cleanup;
9119 void *ud;
9120} cleanup_ent;
9121
9122static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size,
9123 bool owned) {
9124 mem_block *block = ptr;
9125
9126 block->next = a->block_head;
9127 block->size = size;
9128 block->used = align_up_max(sizeof(mem_block));
9129 block->owned = owned;
9130
9131 a->block_head = block;
9132
9133 /* TODO(haberman): ASAN poison. */
9134}
9135
9136
9137static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) {
9138 size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block);
9139 mem_block *block = upb_malloc(a->block_alloc, block_size);
9140
9141 if (!block) {
9142 return NULL;
9143 }
9144
9145 upb_arena_addblock(a, block, block_size, true);
9146 a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size);
9147
9148 return block;
9149}
9150
9151static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
9152 size_t size) {
9153 upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
9154 mem_block *block = a->block_head;
9155 void *ret;
9156
9157 if (size == 0) {
9158 return NULL; /* We are an arena, don't need individual frees. */
9159 }
9160
9161 size = align_up_max(size);
9162
9163 /* TODO(haberman): special-case if this is a realloc of the last alloc? */
9164
9165 if (!block || block->size - block->used < size) {
9166 /* Slow path: have to allocate a new block. */
9167 block = upb_arena_allocblock(a, size);
9168
9169 if (!block) {
9170 return NULL; /* Out of memory. */
9171 }
9172 }
9173
9174 ret = (char*)block + block->used;
9175 block->used += size;
9176
9177 if (oldsize > 0) {
9178 memcpy(ret, ptr, oldsize); /* Preserve existing data. */
9179 }
9180
9181 /* TODO(haberman): ASAN unpoison. */
9182
9183 a->bytes_allocated += size;
9184 return ret;
9185}
9186
9187/* Public Arena API ***********************************************************/
9188
9189void upb_arena_init(upb_arena *a) {
9190 a->alloc.func = &upb_arena_doalloc;
9191 a->block_alloc = &upb_alloc_global;
9192 a->bytes_allocated = 0;
9193 a->next_block_size = 256;
9194 a->max_block_size = 16384;
9195 a->cleanup_head = NULL;
9196 a->block_head = NULL;
9197}
9198
9199void upb_arena_init2(upb_arena *a, void *mem, size_t size, upb_alloc *alloc) {
9200 upb_arena_init(a);
9201
9202 if (size > sizeof(mem_block)) {
9203 upb_arena_addblock(a, mem, size, false);
9204 }
9205
9206 if (alloc) {
9207 a->block_alloc = alloc;
9208 }
9209}
9210
9211void upb_arena_uninit(upb_arena *a) {
9212 cleanup_ent *ent = a->cleanup_head;
9213 mem_block *block = a->block_head;
9214
9215 while (ent) {
9216 ent->cleanup(ent->ud);
9217 ent = ent->next;
9218 }
9219
9220 /* Must do this after running cleanup functions, because this will delete
9221 * the memory we store our cleanup entries in! */
9222 while (block) {
9223 mem_block *next = block->next;
9224
9225 if (block->owned) {
9226 upb_free(a->block_alloc, block);
9227 }
9228
9229 block = next;
9230 }
9231
9232 /* Protect against multiple-uninit. */
9233 a->cleanup_head = NULL;
9234 a->block_head = NULL;
9235}
9236
9237bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud) {
9238 cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent));
9239 if (!ent) {
9240 return false; /* Out of memory. */
9241 }
9242
9243 ent->cleanup = func;
9244 ent->ud = ud;
9245 ent->next = a->cleanup_head;
9246 a->cleanup_head = ent;
9247
9248 return true;
9249}
9250
9251size_t upb_arena_bytesallocated(const upb_arena *a) {
9252 return a->bytes_allocated;
9253}
9254
9255
9256/* Standard error functions ***************************************************/
9257
9258static bool default_err(void *ud, const upb_status *status) {
9259 UPB_UNUSED(ud);
9260 UPB_UNUSED(status);
9261 return false;
9262}
9263
9264static bool write_err_to(void *ud, const upb_status *status) {
9265 upb_status *copy_to = ud;
9266 upb_status_copy(copy_to, status);
9267 return false;
9268}
9269
9270
9271/* upb_env ********************************************************************/
9272
9273void upb_env_initonly(upb_env *e) {
9274 e->ok_ = true;
9275 e->error_func_ = &default_err;
9276 e->error_ud_ = NULL;
9277}
9278
9279void upb_env_init(upb_env *e) {
9280 upb_arena_init(&e->arena_);
9281 upb_env_initonly(e);
9282}
9283
9284void upb_env_init2(upb_env *e, void *mem, size_t n, upb_alloc *alloc) {
9285 upb_arena_init2(&e->arena_, mem, n, alloc);
9286 upb_env_initonly(e);
9287}
9288
9289void upb_env_uninit(upb_env *e) {
9290 upb_arena_uninit(&e->arena_);
9291}
9292
9293void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud) {
9294 e->error_func_ = func;
9295 e->error_ud_ = ud;
9296}
9297
9298void upb_env_reporterrorsto(upb_env *e, upb_status *s) {
9299 e->error_func_ = &write_err_to;
9300 e->error_ud_ = s;
9301}
9302
9303bool upb_env_reporterror(upb_env *e, const upb_status *status) {
9304 e->ok_ = false;
9305 return e->error_func_(e->error_ud_, status);
9306}
9307
9308void *upb_env_malloc(upb_env *e, size_t size) {
9309 return upb_malloc(&e->arena_.alloc, size);
9310}
9311
9312void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
9313 return upb_realloc(&e->arena_.alloc, ptr, oldsize, size);
9314}
9315
9316void upb_env_free(upb_env *e, void *ptr) {
9317 upb_free(&e->arena_.alloc, ptr);
9318}
9319
9320bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
9321 return upb_arena_addcleanup(&e->arena_, func, ud);
9322}
9323
9324size_t upb_env_bytesallocated(const upb_env *e) {
9325 return upb_arena_bytesallocated(&e->arena_);
9326}
9327/* This file was generated by upbc (the upb compiler) from the input
9328 * file:
9329 *
9330 * upb/descriptor/descriptor.proto
9331 *
9332 * Do not edit -- your changes will be discarded when the file is
9333 * regenerated. */
9334
9335
9336static const upb_msgdef msgs[22];
9337static const upb_fielddef fields[107];
9338static const upb_enumdef enums[5];
9339static const upb_tabent strentries[236];
9340static const upb_tabent intentries[18];
9341static const upb_tabval arrays[187];
9342
9343#ifdef UPB_DEBUG_REFS
9344static upb_inttable reftables[268];
9345#endif
9346
9347static const upb_msgdef msgs[22] = {
9348 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, &reftables[0], &reftables[1]),
9349 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, &reftables[2], &reftables[3]),
9350 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, &reftables[4], &reftables[5]),
9351 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, &reftables[6], &reftables[7]),
9352 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, &reftables[8], &reftables[9]),
9353 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, &reftables[10], &reftables[11]),
9354 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, &reftables[12], &reftables[13]),
9355 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, &reftables[14], &reftables[15]),
9356 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, &reftables[16], &reftables[17]),
9357 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, &reftables[18], &reftables[19]),
9358 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, &reftables[20], &reftables[21]),
9359 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, &reftables[22], &reftables[23]),
9360 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, &reftables[24], &reftables[25]),
9361 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, &reftables[26], &reftables[27]),
9362 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, &reftables[28], &reftables[29]),
9363 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, &reftables[30], &reftables[31]),
9364 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, &reftables[32], &reftables[33]),
9365 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, &reftables[34], &reftables[35]),
9366 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, &reftables[36], &reftables[37]),
9367 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, &reftables[38], &reftables[39]),
9368 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, &reftables[40], &reftables[41]),
9369 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, &reftables[42], &reftables[43]),
9370};
9371
9372static const upb_fielddef fields[107] = {
9373 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]),
9374 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]),
9375 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]),
9376 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]),
9377 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]),
9378 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]),
9379 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]),
9380 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]),
9381 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]),
9382 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]),
9383 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]),
9384 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]),
9385 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]),
9386 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]),
9387 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]),
9388 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]),
9389 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]),
9390 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]),
9391 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]),
9392 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]),
9393 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]),
9394 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]),
9395 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]),
9396 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]),
9397 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]),
9398 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]),
9399 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]),
9400 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]),
9401 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]),
9402 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]),
9403 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]),
9404 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]),
9405 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]),
9406 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]),
9407 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]),
9408 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]),
9409 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]),
9410 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]),
9411 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]),
9412 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]),
9413 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]),
9414 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]),
9415 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]),
9416 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]),
9417 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]),
9418 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]),
9419 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]),
9420 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]),
9421 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]),
9422 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]),
9423 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]),
9424 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]),
9425 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]),
9426 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]),
9427 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]),
9428 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]),
9429 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]),
9430 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]),
9431 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]),
9432 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]),
9433 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]),
9434 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]),
9435 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]),
9436 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]),
9437 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]),
9438 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]),
9439 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]),
9440 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]),
9441 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]),
9442 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]),
9443 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]),
9444 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]),
9445 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]),
9446 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]),
9447 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]),
9448 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]),
9449 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]),
9450 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]),
9451 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]),
9452 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]),
9453 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]),
9454 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]),
9455 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]),
9456 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]),
9457 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]),
9458 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]),
9459 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]),
9460 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]),
9461 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]),
9462 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]),
9463 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]),
9464 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]),
9465 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]),
9466 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]),
9467 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]),
9468 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]),
9469 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]),
9470 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]),
9471 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]),
9472 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]),
9473 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]),
9474 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]),
9475 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]),
9476 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]),
9477 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]),
9478 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]),
9479 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]),
9480};
9481
9482static const upb_enumdef enums[5] = {
9483 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]),
9484 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]),
9485 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]),
9486 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]),
9487 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]),
9488};
9489
9490static const upb_tabent strentries[236] = {
9491 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
9492 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9493 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
9494 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
9495 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9496 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9497 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9498 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[25]), &strentries[12]},
9499 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[24]), &strentries[14]},
9500 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9501 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
9502 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9503 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
9504 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
9505 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL},
9506 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), &strentries[13]},
9507 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
9508 {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
9509 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9510 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9511 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[90]), NULL},
9512 {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
9513 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9514 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9515 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9516 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
9517 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
9518 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), &strentries[26]},
9519 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
9520 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
9521 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
9522 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9523 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
9524 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9525 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
9526 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), &strentries[34]},
9527 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
9528 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
9529 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9530 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9531 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
9532 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL},
9533 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9534 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
9535 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9536 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9537 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9538 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9539 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), &strentries[53]},
9540 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9541 {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
9542 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
9543 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
9544 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[95]), &strentries[50]},
9545 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
9546 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
9547 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
9548 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9549 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[105]), NULL},
9550 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9551 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9552 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9553 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9554 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
9555 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL},
9556 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9557 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
9558 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9559 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
9560 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL},
9561 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9562 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9563 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL},
9564 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[106]), NULL},
9565 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9566 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
9567 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[87]), NULL},
9568 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9569 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
9570 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9571 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9572 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[93]), NULL},
9573 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
9574 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
9575 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
9576 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]},
9577 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
9578 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[82]), &strentries[85]},
9579 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9580 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
9581 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9582 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9583 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9584 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9585 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
9586 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), &strentries[116]},
9587 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9588 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9589 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9590 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9591 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9592 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9593 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9594 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL},
9595 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[120]},
9596 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9597 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9598 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
9599 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "php_namespace"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[113]},
9600 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9601 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9602 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9603 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]},
9604 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
9605 {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]},
9606 {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL},
9607 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "php_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
9608 {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]},
9609 {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
9610 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL},
9611 {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
9612 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]},
9613 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "objc_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL},
9614 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "cc_enable_arenas"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL},
9615 {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[128]},
9616 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9617 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9618 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9619 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
9620 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
9621 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
9622 {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL},
9623 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9624 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
9625 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
9626 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
9627 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL},
9628 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9629 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
9630 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
9631 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
9632 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
9633 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9634 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9635 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9636 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9637 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9638 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
9639 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9640 {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]},
9641 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
9642 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[149]},
9643 {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
9644 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
9645 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9646 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9647 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9648 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9649 {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL},
9650 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9651 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9652 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9653 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9654 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[89]), &strentries[167]},
9655 {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]},
9656 {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
9657 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]},
9658 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
9659 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
9660 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9661 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9662 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL},
9663 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9664 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9665 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9666 {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL},
9667 {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "aggregate_value"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL},
9668 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9669 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9670 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9671 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9672 {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
9673 {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
9674 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[92]), &strentries[182]},
9675 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9676 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9677 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
9678 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL},
9679 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[190]},
9680 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9681 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REPEATED"), UPB_TABVALUE_INT_INIT(3), NULL},
9682 {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_OPTIONAL"), UPB_TABVALUE_INT_INIT(1), NULL},
9683 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED64"), UPB_TABVALUE_INT_INIT(6), NULL},
9684 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9685 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9686 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9687 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9688 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_STRING"), UPB_TABVALUE_INT_INIT(9), NULL},
9689 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[221]},
9690 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_DOUBLE"), UPB_TABVALUE_INT_INIT(1), NULL},
9691 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9692 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT32"), UPB_TABVALUE_INT_INIT(5), NULL},
9693 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED32"), UPB_TABVALUE_INT_INIT(15), NULL},
9694 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED32"), UPB_TABVALUE_INT_INIT(7), NULL},
9695 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9696 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[222]},
9697 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9698 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9699 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[219]},
9700 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9701 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9702 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9703 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9704 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_ENUM"), UPB_TABVALUE_INT_INIT(14), NULL},
9705 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT32"), UPB_TABVALUE_INT_INIT(13), NULL},
9706 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9707 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[218]},
9708 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9709 {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED64"), UPB_TABVALUE_INT_INIT(16), NULL},
9710 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_BYTES"), UPB_TABVALUE_INT_INIT(12), NULL},
9711 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT64"), UPB_TABVALUE_INT_INIT(18), NULL},
9712 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_BOOL"), UPB_TABVALUE_INT_INIT(8), NULL},
9713 {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_GROUP"), UPB_TABVALUE_INT_INIT(10), NULL},
9714 {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT32"), UPB_TABVALUE_INT_INIT(17), NULL},
9715 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9716 {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "CORD"), UPB_TABVALUE_INT_INIT(1), NULL},
9717 {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[225]},
9718 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "STRING_PIECE"), UPB_TABVALUE_INT_INIT(2), NULL},
9719 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9720 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NORMAL"), UPB_TABVALUE_INT_INIT(0), NULL},
9721 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NUMBER"), UPB_TABVALUE_INT_INIT(2), NULL},
9722 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_STRING"), UPB_TABVALUE_INT_INIT(1), NULL},
9723 {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "CODE_SIZE"), UPB_TABVALUE_INT_INIT(2), NULL},
9724 {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[235]},
9725 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9726 {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "LITE_RUNTIME"), UPB_TABVALUE_INT_INIT(3), NULL},
9727};
9728
9729static const upb_tabent intentries[18] = {
9730 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9731 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
9732 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9733 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
9734 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9735 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
9736 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9737 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
9738 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9739 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
9740 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9741 {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
9742 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9743 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
9744 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9745 {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
9746 {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
9747 {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
9748};
9749
9750static const upb_tabval arrays[187] = {
9751 UPB_TABVALUE_EMPTY_INIT,
9752 UPB_TABVALUE_PTR_INIT(&fields[57]),
9753 UPB_TABVALUE_PTR_INIT(&fields[25]),
9754 UPB_TABVALUE_PTR_INIT(&fields[60]),
9755 UPB_TABVALUE_PTR_INIT(&fields[20]),
9756 UPB_TABVALUE_PTR_INIT(&fields[24]),
9757 UPB_TABVALUE_PTR_INIT(&fields[22]),
9758 UPB_TABVALUE_PTR_INIT(&fields[68]),
9759 UPB_TABVALUE_PTR_INIT(&fields[65]),
9760 UPB_TABVALUE_PTR_INIT(&fields[85]),
9761 UPB_TABVALUE_PTR_INIT(&fields[84]),
9762 UPB_TABVALUE_EMPTY_INIT,
9763 UPB_TABVALUE_PTR_INIT(&fields[91]),
9764 UPB_TABVALUE_PTR_INIT(&fields[18]),
9765 UPB_TABVALUE_EMPTY_INIT,
9766 UPB_TABVALUE_PTR_INIT(&fields[90]),
9767 UPB_TABVALUE_PTR_INIT(&fields[17]),
9768 UPB_TABVALUE_EMPTY_INIT,
9769 UPB_TABVALUE_PTR_INIT(&fields[52]),
9770 UPB_TABVALUE_PTR_INIT(&fields[104]),
9771 UPB_TABVALUE_PTR_INIT(&fields[73]),
9772 UPB_TABVALUE_EMPTY_INIT,
9773 UPB_TABVALUE_EMPTY_INIT,
9774 UPB_TABVALUE_PTR_INIT(&fields[1]),
9775 UPB_TABVALUE_PTR_INIT(&fields[14]),
9776 UPB_TABVALUE_EMPTY_INIT,
9777 UPB_TABVALUE_PTR_INIT(&fields[50]),
9778 UPB_TABVALUE_PTR_INIT(&fields[63]),
9779 UPB_TABVALUE_PTR_INIT(&fields[74]),
9780 UPB_TABVALUE_EMPTY_INIT,
9781 UPB_TABVALUE_PTR_INIT(&fields[13]),
9782 UPB_TABVALUE_EMPTY_INIT,
9783 UPB_TABVALUE_PTR_INIT(&fields[56]),
9784 UPB_TABVALUE_PTR_INIT(&fields[21]),
9785 UPB_TABVALUE_PTR_INIT(&fields[62]),
9786 UPB_TABVALUE_PTR_INIT(&fields[40]),
9787 UPB_TABVALUE_PTR_INIT(&fields[95]),
9788 UPB_TABVALUE_PTR_INIT(&fields[96]),
9789 UPB_TABVALUE_PTR_INIT(&fields[7]),
9790 UPB_TABVALUE_PTR_INIT(&fields[70]),
9791 UPB_TABVALUE_PTR_INIT(&fields[66]),
9792 UPB_TABVALUE_PTR_INIT(&fields[38]),
9793 UPB_TABVALUE_EMPTY_INIT,
9794 UPB_TABVALUE_PTR_INIT(&fields[6]),
9795 UPB_TABVALUE_PTR_INIT(&fields[77]),
9796 UPB_TABVALUE_PTR_INIT(&fields[9]),
9797 UPB_TABVALUE_EMPTY_INIT,
9798 UPB_TABVALUE_PTR_INIT(&fields[41]),
9799 UPB_TABVALUE_PTR_INIT(&fields[39]),
9800 UPB_TABVALUE_EMPTY_INIT,
9801 UPB_TABVALUE_EMPTY_INIT,
9802 UPB_TABVALUE_EMPTY_INIT,
9803 UPB_TABVALUE_PTR_INIT(&fields[105]),
9804 UPB_TABVALUE_EMPTY_INIT,
9805 UPB_TABVALUE_PTR_INIT(&fields[51]),
9806 UPB_TABVALUE_PTR_INIT(&fields[76]),
9807 UPB_TABVALUE_PTR_INIT(&fields[8]),
9808 UPB_TABVALUE_PTR_INIT(&fields[47]),
9809 UPB_TABVALUE_PTR_INIT(&fields[19]),
9810 UPB_TABVALUE_PTR_INIT(&fields[87]),
9811 UPB_TABVALUE_PTR_INIT(&fields[23]),
9812 UPB_TABVALUE_PTR_INIT(&fields[69]),
9813 UPB_TABVALUE_PTR_INIT(&fields[88]),
9814 UPB_TABVALUE_PTR_INIT(&fields[82]),
9815 UPB_TABVALUE_PTR_INIT(&fields[106]),
9816 UPB_TABVALUE_PTR_INIT(&fields[93]),
9817 UPB_TABVALUE_EMPTY_INIT,
9818 UPB_TABVALUE_PTR_INIT(&fields[26]),
9819 UPB_TABVALUE_EMPTY_INIT,
9820 UPB_TABVALUE_PTR_INIT(&fields[35]),
9821 UPB_TABVALUE_EMPTY_INIT,
9822 UPB_TABVALUE_EMPTY_INIT,
9823 UPB_TABVALUE_EMPTY_INIT,
9824 UPB_TABVALUE_EMPTY_INIT,
9825 UPB_TABVALUE_EMPTY_INIT,
9826 UPB_TABVALUE_EMPTY_INIT,
9827 UPB_TABVALUE_PTR_INIT(&fields[34]),
9828 UPB_TABVALUE_PTR_INIT(&fields[67]),
9829 UPB_TABVALUE_PTR_INIT(&fields[33]),
9830 UPB_TABVALUE_PTR_INIT(&fields[27]),
9831 UPB_TABVALUE_EMPTY_INIT,
9832 UPB_TABVALUE_EMPTY_INIT,
9833 UPB_TABVALUE_EMPTY_INIT,
9834 UPB_TABVALUE_EMPTY_INIT,
9835 UPB_TABVALUE_PTR_INIT(&fields[3]),
9836 UPB_TABVALUE_PTR_INIT(&fields[32]),
9837 UPB_TABVALUE_PTR_INIT(&fields[83]),
9838 UPB_TABVALUE_EMPTY_INIT,
9839 UPB_TABVALUE_PTR_INIT(&fields[31]),
9840 UPB_TABVALUE_EMPTY_INIT,
9841 UPB_TABVALUE_EMPTY_INIT,
9842 UPB_TABVALUE_PTR_INIT(&fields[12]),
9843 UPB_TABVALUE_EMPTY_INIT,
9844 UPB_TABVALUE_EMPTY_INIT,
9845 UPB_TABVALUE_EMPTY_INIT,
9846 UPB_TABVALUE_PTR_INIT(&fields[36]),
9847 UPB_TABVALUE_EMPTY_INIT,
9848 UPB_TABVALUE_EMPTY_INIT,
9849 UPB_TABVALUE_EMPTY_INIT,
9850 UPB_TABVALUE_PTR_INIT(&fields[2]),
9851 UPB_TABVALUE_EMPTY_INIT,
9852 UPB_TABVALUE_EMPTY_INIT,
9853 UPB_TABVALUE_EMPTY_INIT,
9854 UPB_TABVALUE_EMPTY_INIT,
9855 UPB_TABVALUE_PTR_INIT(&fields[64]),
9856 UPB_TABVALUE_PTR_INIT(&fields[5]),
9857 UPB_TABVALUE_PTR_INIT(&fields[37]),
9858 UPB_TABVALUE_EMPTY_INIT,
9859 UPB_TABVALUE_PTR_INIT(&fields[79]),
9860 UPB_TABVALUE_PTR_INIT(&fields[80]),
9861 UPB_TABVALUE_EMPTY_INIT,
9862 UPB_TABVALUE_PTR_INIT(&fields[46]),
9863 UPB_TABVALUE_PTR_INIT(&fields[61]),
9864 UPB_TABVALUE_PTR_INIT(&fields[11]),
9865 UPB_TABVALUE_EMPTY_INIT,
9866 UPB_TABVALUE_EMPTY_INIT,
9867 UPB_TABVALUE_EMPTY_INIT,
9868 UPB_TABVALUE_PTR_INIT(&fields[45]),
9869 UPB_TABVALUE_EMPTY_INIT,
9870 UPB_TABVALUE_PTR_INIT(&fields[55]),
9871 UPB_TABVALUE_PTR_INIT(&fields[29]),
9872 UPB_TABVALUE_PTR_INIT(&fields[75]),
9873 UPB_TABVALUE_PTR_INIT(&fields[71]),
9874 UPB_TABVALUE_PTR_INIT(&fields[4]),
9875 UPB_TABVALUE_PTR_INIT(&fields[86]),
9876 UPB_TABVALUE_EMPTY_INIT,
9877 UPB_TABVALUE_EMPTY_INIT,
9878 UPB_TABVALUE_PTR_INIT(&fields[54]),
9879 UPB_TABVALUE_EMPTY_INIT,
9880 UPB_TABVALUE_PTR_INIT(&fields[53]),
9881 UPB_TABVALUE_PTR_INIT(&fields[48]),
9882 UPB_TABVALUE_PTR_INIT(&fields[72]),
9883 UPB_TABVALUE_EMPTY_INIT,
9884 UPB_TABVALUE_EMPTY_INIT,
9885 UPB_TABVALUE_PTR_INIT(&fields[44]),
9886 UPB_TABVALUE_EMPTY_INIT,
9887 UPB_TABVALUE_PTR_INIT(&fields[78]),
9888 UPB_TABVALUE_PTR_INIT(&fields[89]),
9889 UPB_TABVALUE_PTR_INIT(&fields[42]),
9890 UPB_TABVALUE_PTR_INIT(&fields[94]),
9891 UPB_TABVALUE_EMPTY_INIT,
9892 UPB_TABVALUE_PTR_INIT(&fields[43]),
9893 UPB_TABVALUE_EMPTY_INIT,
9894 UPB_TABVALUE_EMPTY_INIT,
9895 UPB_TABVALUE_PTR_INIT(&fields[49]),
9896 UPB_TABVALUE_PTR_INIT(&fields[28]),
9897 UPB_TABVALUE_PTR_INIT(&fields[81]),
9898 UPB_TABVALUE_PTR_INIT(&fields[59]),
9899 UPB_TABVALUE_PTR_INIT(&fields[16]),
9900 UPB_TABVALUE_PTR_INIT(&fields[92]),
9901 UPB_TABVALUE_PTR_INIT(&fields[0]),
9902 UPB_TABVALUE_EMPTY_INIT,
9903 UPB_TABVALUE_PTR_INIT(&fields[58]),
9904 UPB_TABVALUE_PTR_INIT(&fields[30]),
9905 UPB_TABVALUE_EMPTY_INIT,
9906 UPB_TABVALUE_PTR_INIT("LABEL_OPTIONAL"),
9907 UPB_TABVALUE_PTR_INIT("LABEL_REQUIRED"),
9908 UPB_TABVALUE_PTR_INIT("LABEL_REPEATED"),
9909 UPB_TABVALUE_EMPTY_INIT,
9910 UPB_TABVALUE_PTR_INIT("TYPE_DOUBLE"),
9911 UPB_TABVALUE_PTR_INIT("TYPE_FLOAT"),
9912 UPB_TABVALUE_PTR_INIT("TYPE_INT64"),
9913 UPB_TABVALUE_PTR_INIT("TYPE_UINT64"),
9914 UPB_TABVALUE_PTR_INIT("TYPE_INT32"),
9915 UPB_TABVALUE_PTR_INIT("TYPE_FIXED64"),
9916 UPB_TABVALUE_PTR_INIT("TYPE_FIXED32"),
9917 UPB_TABVALUE_PTR_INIT("TYPE_BOOL"),
9918 UPB_TABVALUE_PTR_INIT("TYPE_STRING"),
9919 UPB_TABVALUE_PTR_INIT("TYPE_GROUP"),
9920 UPB_TABVALUE_PTR_INIT("TYPE_MESSAGE"),
9921 UPB_TABVALUE_PTR_INIT("TYPE_BYTES"),
9922 UPB_TABVALUE_PTR_INIT("TYPE_UINT32"),
9923 UPB_TABVALUE_PTR_INIT("TYPE_ENUM"),
9924 UPB_TABVALUE_PTR_INIT("TYPE_SFIXED32"),
9925 UPB_TABVALUE_PTR_INIT("TYPE_SFIXED64"),
9926 UPB_TABVALUE_PTR_INIT("TYPE_SINT32"),
9927 UPB_TABVALUE_PTR_INIT("TYPE_SINT64"),
9928 UPB_TABVALUE_PTR_INIT("STRING"),
9929 UPB_TABVALUE_PTR_INIT("CORD"),
9930 UPB_TABVALUE_PTR_INIT("STRING_PIECE"),
9931 UPB_TABVALUE_PTR_INIT("JS_NORMAL"),
9932 UPB_TABVALUE_PTR_INIT("JS_STRING"),
9933 UPB_TABVALUE_PTR_INIT("JS_NUMBER"),
9934 UPB_TABVALUE_EMPTY_INIT,
9935 UPB_TABVALUE_PTR_INIT("SPEED"),
9936 UPB_TABVALUE_PTR_INIT("CODE_SIZE"),
9937 UPB_TABVALUE_PTR_INIT("LITE_RUNTIME"),
9938};
9939
9940#ifdef UPB_DEBUG_REFS
9941static upb_inttable reftables[268] = {
9942 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9943 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9944 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9945 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9946 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9947 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9948 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9949 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9950 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9951 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9952 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9953 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9954 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9955 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9956 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9957 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9958 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9959 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9960 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9961 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9962 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9963 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9964 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9965 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9966 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9967 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9968 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9969 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9970 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9971 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9972 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9973 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9974 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9975 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9976 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9977 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9978 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9979 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9980 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9981 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9982 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9983 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9984 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9985 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9986 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9987 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9988 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9989 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9990 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9991 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9992 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9993 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9994 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9995 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9996 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9997 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9998 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
9999 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10000 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10001 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10002 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10003 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10004 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10005 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10006 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10007 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10008 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10009 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10010 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10011 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10012 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10013 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10014 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10015 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10016 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10017 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10018 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10019 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10020 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10021 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10022 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10023 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10024 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10025 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10026 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10027 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10028 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10029 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10030 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10031 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10032 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10033 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10034 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10035 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10036 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10037 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10038 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10039 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10040 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10041 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10042 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10043 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10044 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10045 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10046 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10047 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10048 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10049 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10050 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10051 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10052 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10053 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10054 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10055 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10056 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10057 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10058 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10059 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10060 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10061 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10062 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10063 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10064 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10065 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10066 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10067 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10068 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10069 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10070 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10071 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10072 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10073 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10074 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10075 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10076 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10077 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10078 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10079 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10080 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10081 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10082 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10083 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10084 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10085 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10086 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10087 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10088 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10089 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10090 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10091 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10092 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10093 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10094 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10095 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10096 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10097 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10098 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10099 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10100 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10101 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10102 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10103 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10104 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10105 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10106 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10107 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10108 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10109 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10110 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10111 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10112 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10113 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10114 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10115 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10116 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10117 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10118 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10119 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10120 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10121 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10122 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10123 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10124 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10125 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10126 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10127 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10128 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10129 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10130 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10131 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10132 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10133 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10134 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10135 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10136 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10137 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10138 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10139 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10140 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10141 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10142 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10143 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10144 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10145 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10146 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10147 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10148 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10149 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10150 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10151 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10152 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10153 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10154 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10155 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10156 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10157 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10158 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10159 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10160 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10161 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10162 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10163 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10164 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10165 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10166 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10167 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10168 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10169 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10170 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10171 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10172 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10173 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10174 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10175 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10176 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10177 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10178 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10179 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10180 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10181 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10182 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10183 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10184 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10185 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10186 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10187 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10188 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10189 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10190 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10191 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10192 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10193 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10194 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10195 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10196 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10197 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10198 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10199 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10200 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10201 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10202 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10203 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10204 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10205 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10206 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10207 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10208 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10209 UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
10210};
10211#endif
10212
10213static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) {
10214 upb_msgdef_ref(m, owner);
10215 return m;
10216}
10217
10218static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) {
10219 upb_enumdef_ref(e, owner);
10220 return e;
10221}
10222
10223/* Public API. */
10224const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner) { return refm(&msgs[0], owner); }
10225const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner) { return refm(&msgs[1], owner); }
10226const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(const void *owner) { return refm(&msgs[2], owner); }
10227const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto_get(const void *owner) { return refm(&msgs[3], owner); }
10228const upb_msgdef *upbdefs_google_protobuf_EnumOptions_get(const void *owner) { return refm(&msgs[4], owner); }
10229const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto_get(const void *owner) { return refm(&msgs[5], owner); }
10230const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions_get(const void *owner) { return refm(&msgs[6], owner); }
10231const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto_get(const void *owner) { return refm(&msgs[7], owner); }
10232const upb_msgdef *upbdefs_google_protobuf_FieldOptions_get(const void *owner) { return refm(&msgs[8], owner); }
10233const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto_get(const void *owner) { return refm(&msgs[9], owner); }
10234const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet_get(const void *owner) { return refm(&msgs[10], owner); }
10235const upb_msgdef *upbdefs_google_protobuf_FileOptions_get(const void *owner) { return refm(&msgs[11], owner); }
10236const upb_msgdef *upbdefs_google_protobuf_MessageOptions_get(const void *owner) { return refm(&msgs[12], owner); }
10237const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto_get(const void *owner) { return refm(&msgs[13], owner); }
10238const upb_msgdef *upbdefs_google_protobuf_MethodOptions_get(const void *owner) { return refm(&msgs[14], owner); }
10239const upb_msgdef *upbdefs_google_protobuf_OneofDescriptorProto_get(const void *owner) { return refm(&msgs[15], owner); }
10240const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto_get(const void *owner) { return refm(&msgs[16], owner); }
10241const upb_msgdef *upbdefs_google_protobuf_ServiceOptions_get(const void *owner) { return refm(&msgs[17], owner); }
10242const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_get(const void *owner) { return refm(&msgs[18], owner); }
10243const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location_get(const void *owner) { return refm(&msgs[19], owner); }
10244const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_get(const void *owner) { return refm(&msgs[20], owner); }
10245const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart_get(const void *owner) { return refm(&msgs[21], owner); }
10246
10247const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label_get(const void *owner) { return refe(&enums[0], owner); }
10248const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type_get(const void *owner) { return refe(&enums[1], owner); }
10249const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType_get(const void *owner) { return refe(&enums[2], owner); }
10250const upb_enumdef *upbdefs_google_protobuf_FieldOptions_JSType_get(const void *owner) { return refe(&enums[3], owner); }
10251const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode_get(const void *owner) { return refe(&enums[4], owner); }
10252/*
10253** XXX: The routines in this file that consume a string do not currently
10254** support having the string span buffers. In the future, as upb_sink and
10255** its buffering/sharing functionality evolve there should be an easy and
10256** idiomatic way of correctly handling this case. For now, we accept this
10257** limitation since we currently only parse descriptors from single strings.
10258*/
10259
10260
10261#include <errno.h>
10262#include <stdlib.h>
10263#include <string.h>
10264
10265/* Compares a NULL-terminated string with a non-NULL-terminated string. */
10266static bool upb_streq(const char *str, const char *buf, size_t n) {
10267 return strlen(str) == n && memcmp(str, buf, n) == 0;
10268}
10269
10270/* We keep a stack of all the messages scopes we are currently in, as well as
10271 * the top-level file scope. This is necessary to correctly qualify the
10272 * definitions that are contained inside. "name" tracks the name of the
10273 * message or package (a bare name -- not qualified by any enclosing scopes). */
10274typedef struct {
10275 char *name;
10276 /* Index of the first def that is under this scope. For msgdefs, the
10277 * msgdef itself is at start-1. */
10278 int start;
10279 uint32_t oneof_start;
10280 uint32_t oneof_index;
10281} upb_descreader_frame;
10282
10283/* The maximum number of nested declarations that are allowed, ie.
10284 * message Foo {
10285 * message Bar {
10286 * message Baz {
10287 * }
10288 * }
10289 * }
10290 *
10291 * This is a resource limit that affects how big our runtime stack can grow.
10292 * TODO: make this a runtime-settable property of the Reader instance. */
10293#define UPB_MAX_MESSAGE_NESTING 64
10294
10295struct upb_descreader {
10296 upb_sink sink;
10297 upb_inttable files;
10298 upb_strtable files_by_name;
10299 upb_filedef *file; /* The last file in files. */
10300 upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
10301 int stack_len;
10302 upb_inttable oneofs;
10303
10304 uint32_t number;
10305 char *name;
10306 bool saw_number;
10307 bool saw_name;
10308
10309 char *default_string;
10310
10311 upb_fielddef *f;
10312};
10313
10314static char *upb_gstrndup(const char *buf, size_t n) {
10315 char *ret = upb_gmalloc(n + 1);
10316 if (!ret) return NULL;
10317 memcpy(ret, buf, n);
10318 ret[n] = '\0';
10319 return ret;
10320}
10321
10322/* Returns a newly allocated string that joins input strings together, for
10323 * example:
10324 * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
10325 * join("", "Baz") -> "Baz"
10326 * Caller owns a ref on the returned string. */
10327static char *upb_join(const char *base, const char *name) {
10328 if (!base || strlen(base) == 0) {
10329 return upb_gstrdup(name);
10330 } else {
10331 char *ret = upb_gmalloc(strlen(base) + strlen(name) + 2);
10332 if (!ret) {
10333 return NULL;
10334 }
10335 ret[0] = '\0';
10336 strcat(ret, base);
10337 strcat(ret, ".");
10338 strcat(ret, name);
10339 return ret;
10340 }
10341}
10342
10343/* Qualify the defname for all defs starting with offset "start" with "str". */
10344static bool upb_descreader_qualify(upb_filedef *f, char *str, int32_t start) {
10345 size_t i;
10346 for (i = start; i < upb_filedef_defcount(f); i++) {
10347 upb_def *def = upb_filedef_mutabledef(f, i);
10348 char *name = upb_join(str, upb_def_fullname(def));
10349 if (!name) {
10350 /* Need better logic here; at this point we've qualified some names but
10351 * not others. */
10352 return false;
10353 }
10354 upb_def_setfullname(def, name, NULL);
10355 upb_gfree(name);
10356 }
10357 return true;
10358}
10359
10360
10361/* upb_descreader ************************************************************/
10362
10363static upb_msgdef *upb_descreader_top(upb_descreader *r) {
10364 int index;
10365 UPB_ASSERT(r->stack_len > 1);
10366 index = r->stack[r->stack_len-1].start - 1;
10367 UPB_ASSERT(index >= 0);
10368 return upb_downcast_msgdef_mutable(upb_filedef_mutabledef(r->file, index));
10369}
10370
10371static upb_def *upb_descreader_last(upb_descreader *r) {
10372 return upb_filedef_mutabledef(r->file, upb_filedef_defcount(r->file) - 1);
10373}
10374
10375/* Start/end handlers for FileDescriptorProto and DescriptorProto (the two
10376 * entities that have names and can contain sub-definitions. */
10377void upb_descreader_startcontainer(upb_descreader *r) {
10378 upb_descreader_frame *f = &r->stack[r->stack_len++];
10379 f->start = upb_filedef_defcount(r->file);
10380 f->oneof_start = upb_inttable_count(&r->oneofs);
10381 f->oneof_index = 0;
10382 f->name = NULL;
10383}
10384
10385bool upb_descreader_endcontainer(upb_descreader *r) {
10386 upb_descreader_frame *f = &r->stack[r->stack_len - 1];
10387
10388 while (upb_inttable_count(&r->oneofs) > f->oneof_start) {
10389 upb_oneofdef *o = upb_value_getptr(upb_inttable_pop(&r->oneofs));
10390 bool ok = upb_msgdef_addoneof(upb_descreader_top(r), o, &r->oneofs, NULL);
10391 UPB_ASSERT(ok);
10392 }
10393
10394 if (!upb_descreader_qualify(r->file, f->name, f->start)) {
10395 return false;
10396 }
10397 upb_gfree(f->name);
10398 f->name = NULL;
10399
10400 r->stack_len--;
10401 return true;
10402}
10403
10404void upb_descreader_setscopename(upb_descreader *r, char *str) {
10405 upb_descreader_frame *f = &r->stack[r->stack_len-1];
10406 upb_gfree(f->name);
10407 f->name = str;
10408}
10409
10410static upb_oneofdef *upb_descreader_getoneof(upb_descreader *r,
10411 uint32_t index) {
10412 bool found;
10413 upb_value val;
10414 upb_descreader_frame *f = &r->stack[r->stack_len-1];
10415
10416 /* DescriptorProto messages can be nested, so we will see the nested messages
10417 * between when we see the FieldDescriptorProto and the OneofDescriptorProto.
10418 * We need to preserve the oneofs in between these two things. */
10419 index += f->oneof_start;
10420
10421 while (upb_inttable_count(&r->oneofs) <= index) {
10422 upb_inttable_push(&r->oneofs, upb_value_ptr(upb_oneofdef_new(&r->oneofs)));
10423 }
10424
10425 found = upb_inttable_lookup(&r->oneofs, index, &val);
10426 UPB_ASSERT(found);
10427 return upb_value_getptr(val);
10428}
10429
10430/** Handlers for google.protobuf.FileDescriptorSet. ***************************/
10431
10432static void *fileset_startfile(void *closure, const void *hd) {
10433 upb_descreader *r = closure;
10434 UPB_UNUSED(hd);
10435 r->file = upb_filedef_new(&r->files);
10436 upb_inttable_push(&r->files, upb_value_ptr(r->file));
10437 return r;
10438}
10439
10440/** Handlers for google.protobuf.FileDescriptorProto. *************************/
10441
10442static bool file_start(void *closure, const void *hd) {
10443 upb_descreader *r = closure;
10444 UPB_UNUSED(hd);
10445 upb_descreader_startcontainer(r);
10446 return true;
10447}
10448
10449static bool file_end(void *closure, const void *hd, upb_status *status) {
10450 upb_descreader *r = closure;
10451 UPB_UNUSED(hd);
10452 UPB_UNUSED(status);
10453 return upb_descreader_endcontainer(r);
10454}
10455
10456static size_t file_onname(void *closure, const void *hd, const char *buf,
10457 size_t n, const upb_bufhandle *handle) {
10458 upb_descreader *r = closure;
10459 char *name;
10460 bool ok;
10461 UPB_UNUSED(hd);
10462 UPB_UNUSED(handle);
10463
10464 name = upb_gstrndup(buf, n);
10465 upb_strtable_insert(&r->files_by_name, name, upb_value_ptr(r->file));
10466 /* XXX: see comment at the top of the file. */
10467 ok = upb_filedef_setname(r->file, name, NULL);
10468 upb_gfree(name);
10469 UPB_ASSERT(ok);
10470 return n;
10471}
10472
10473static size_t file_onpackage(void *closure, const void *hd, const char *buf,
10474 size_t n, const upb_bufhandle *handle) {
10475 upb_descreader *r = closure;
10476 char *package;
10477 bool ok;
10478 UPB_UNUSED(hd);
10479 UPB_UNUSED(handle);
10480
10481 package = upb_gstrndup(buf, n);
10482 /* XXX: see comment at the top of the file. */
10483 upb_descreader_setscopename(r, package);
10484 ok = upb_filedef_setpackage(r->file, package, NULL);
10485 UPB_ASSERT(ok);
10486 return n;
10487}
10488
10489static void *file_startphpnamespace(void *closure, const void *hd,
10490 size_t size_hint) {
10491 upb_descreader *r = closure;
10492 bool ok;
10493 UPB_UNUSED(hd);
10494 UPB_UNUSED(size_hint);
10495
10496 ok = upb_filedef_setphpnamespace(r->file, "", NULL);
10497 UPB_ASSERT(ok);
10498 return closure;
10499}
10500
10501static size_t file_onphpnamespace(void *closure, const void *hd,
10502 const char *buf, size_t n,
10503 const upb_bufhandle *handle) {
10504 upb_descreader *r = closure;
10505 char *php_namespace;
10506 bool ok;
10507 UPB_UNUSED(hd);
10508 UPB_UNUSED(handle);
10509
10510 php_namespace = upb_gstrndup(buf, n);
10511 ok = upb_filedef_setphpnamespace(r->file, php_namespace, NULL);
10512 upb_gfree(php_namespace);
10513 UPB_ASSERT(ok);
10514 return n;
10515}
10516
10517static size_t file_onphpprefix(void *closure, const void *hd, const char *buf,
10518 size_t n, const upb_bufhandle *handle) {
10519 upb_descreader *r = closure;
10520 char *prefix;
10521 bool ok;
10522 UPB_UNUSED(hd);
10523 UPB_UNUSED(handle);
10524
10525 prefix = upb_gstrndup(buf, n);
10526 ok = upb_filedef_setphpprefix(r->file, prefix, NULL);
10527 upb_gfree(prefix);
10528 UPB_ASSERT(ok);
10529 return n;
10530}
10531
10532static size_t file_onsyntax(void *closure, const void *hd, const char *buf,
10533 size_t n, const upb_bufhandle *handle) {
10534 upb_descreader *r = closure;
10535 bool ok;
10536 UPB_UNUSED(hd);
10537 UPB_UNUSED(handle);
10538 /* XXX: see comment at the top of the file. */
10539 if (upb_streq("proto2", buf, n)) {
10540 ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO2, NULL);
10541 } else if (upb_streq("proto3", buf, n)) {
10542 ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO3, NULL);
10543 } else {
10544 ok = false;
10545 }
10546
10547 UPB_ASSERT(ok);
10548 return n;
10549}
10550
10551static void *file_startmsg(void *closure, const void *hd) {
10552 upb_descreader *r = closure;
10553 upb_msgdef *m = upb_msgdef_new(&m);
10554 bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
10555 UPB_UNUSED(hd);
10556 UPB_ASSERT(ok);
10557 return r;
10558}
10559
10560static void *file_startenum(void *closure, const void *hd) {
10561 upb_descreader *r = closure;
10562 upb_enumdef *e = upb_enumdef_new(&e);
10563 bool ok = upb_filedef_addenum(r->file, e, &e, NULL);
10564 UPB_UNUSED(hd);
10565 UPB_ASSERT(ok);
10566 return r;
10567}
10568
10569static void *file_startext(void *closure, const void *hd) {
10570 upb_descreader *r = closure;
10571 bool ok;
10572 r->f = upb_fielddef_new(r);
10573 ok = upb_filedef_addext(r->file, r->f, r, NULL);
10574 UPB_UNUSED(hd);
10575 UPB_ASSERT(ok);
10576 return r;
10577}
10578
10579static size_t file_ondep(void *closure, const void *hd, const char *buf,
10580 size_t n, const upb_bufhandle *handle) {
10581 upb_descreader *r = closure;
10582 upb_value val;
10583 if (upb_strtable_lookup2(&r->files_by_name, buf, n, &val)) {
10584 upb_filedef_adddep(r->file, upb_value_getptr(val));
10585 }
10586 UPB_UNUSED(hd);
10587 UPB_UNUSED(handle);
10588 return n;
10589}
10590
10591/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/
10592
10593static bool enumval_startmsg(void *closure, const void *hd) {
10594 upb_descreader *r = closure;
10595 UPB_UNUSED(hd);
10596 r->saw_number = false;
10597 r->saw_name = false;
10598 return true;
10599}
10600
10601static size_t enumval_onname(void *closure, const void *hd, const char *buf,
10602 size_t n, const upb_bufhandle *handle) {
10603 upb_descreader *r = closure;
10604 UPB_UNUSED(hd);
10605 UPB_UNUSED(handle);
10606 /* XXX: see comment at the top of the file. */
10607 upb_gfree(r->name);
10608 r->name = upb_gstrndup(buf, n);
10609 r->saw_name = true;
10610 return n;
10611}
10612
10613static bool enumval_onnumber(void *closure, const void *hd, int32_t val) {
10614 upb_descreader *r = closure;
10615 UPB_UNUSED(hd);
10616 r->number = val;
10617 r->saw_number = true;
10618 return true;
10619}
10620
10621static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) {
10622 upb_descreader *r = closure;
10623 upb_enumdef *e;
10624 UPB_UNUSED(hd);
10625
10626 if(!r->saw_number || !r->saw_name) {
10627 upb_status_seterrmsg(status, "Enum value missing name or number.");
10628 return false;
10629 }
10630 e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
10631 upb_enumdef_addval(e, r->name, r->number, status);
10632 upb_gfree(r->name);
10633 r->name = NULL;
10634 return true;
10635}
10636
10637/** Handlers for google.protobuf.EnumDescriptorProto. *************************/
10638
10639static bool enum_endmsg(void *closure, const void *hd, upb_status *status) {
10640 upb_descreader *r = closure;
10641 upb_enumdef *e;
10642 UPB_UNUSED(hd);
10643
10644 e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
10645 if (upb_def_fullname(upb_descreader_last(r)) == NULL) {
10646 upb_status_seterrmsg(status, "Enum had no name.");
10647 return false;
10648 }
10649 if (upb_enumdef_numvals(e) == 0) {
10650 upb_status_seterrmsg(status, "Enum had no values.");
10651 return false;
10652 }
10653 return true;
10654}
10655
10656static size_t enum_onname(void *closure, const void *hd, const char *buf,
10657 size_t n, const upb_bufhandle *handle) {
10658 upb_descreader *r = closure;
10659 char *fullname = upb_gstrndup(buf, n);
10660 UPB_UNUSED(hd);
10661 UPB_UNUSED(handle);
10662 /* XXX: see comment at the top of the file. */
10663 upb_def_setfullname(upb_descreader_last(r), fullname, NULL);
10664 upb_gfree(fullname);
10665 return n;
10666}
10667
10668/** Handlers for google.protobuf.FieldDescriptorProto *************************/
10669
10670static bool field_startmsg(void *closure, const void *hd) {
10671 upb_descreader *r = closure;
10672 UPB_UNUSED(hd);
10673 UPB_ASSERT(r->f);
10674 upb_gfree(r->default_string);
10675 r->default_string = NULL;
10676
10677 /* fielddefs default to packed, but descriptors default to non-packed. */
10678 upb_fielddef_setpacked(r->f, false);
10679 return true;
10680}
10681
10682/* Converts the default value in string "str" into "d". Passes a ref on str.
10683 * Returns true on success. */
10684static bool parse_default(char *str, upb_fielddef *f) {
10685 bool success = true;
10686 char *end;
10687 switch (upb_fielddef_type(f)) {
10688 case UPB_TYPE_INT32: {
10689 long val = strtol(str, &end, 0);
10690 if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end)
10691 success = false;
10692 else
10693 upb_fielddef_setdefaultint32(f, val);
10694 break;
10695 }
10696 case UPB_TYPE_INT64: {
10697 /* XXX: Need to write our own strtoll, since it's not available in c89. */
10698 long long val = strtol(str, &end, 0);
10699 if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end)
10700 success = false;
10701 else
10702 upb_fielddef_setdefaultint64(f, val);
10703 break;
10704 }
10705 case UPB_TYPE_UINT32: {
10706 unsigned long val = strtoul(str, &end, 0);
10707 if (val > UINT32_MAX || errno == ERANGE || *end)
10708 success = false;
10709 else
10710 upb_fielddef_setdefaultuint32(f, val);
10711 break;
10712 }
10713 case UPB_TYPE_UINT64: {
10714 /* XXX: Need to write our own strtoull, since it's not available in c89. */
10715 unsigned long long val = strtoul(str, &end, 0);
10716 if (val > UINT64_MAX || errno == ERANGE || *end)
10717 success = false;
10718 else
10719 upb_fielddef_setdefaultuint64(f, val);
10720 break;
10721 }
10722 case UPB_TYPE_DOUBLE: {
10723 double val = strtod(str, &end);
10724 if (errno == ERANGE || *end)
10725 success = false;
10726 else
10727 upb_fielddef_setdefaultdouble(f, val);
10728 break;
10729 }
10730 case UPB_TYPE_FLOAT: {
10731 /* XXX: Need to write our own strtof, since it's not available in c89. */
10732 float val = strtod(str, &end);
10733 if (errno == ERANGE || *end)
10734 success = false;
10735 else
10736 upb_fielddef_setdefaultfloat(f, val);
10737 break;
10738 }
10739 case UPB_TYPE_BOOL: {
10740 if (strcmp(str, "false") == 0)
10741 upb_fielddef_setdefaultbool(f, false);
10742 else if (strcmp(str, "true") == 0)
10743 upb_fielddef_setdefaultbool(f, true);
10744 else
10745 success = false;
10746 break;
10747 }
10748 default: abort();
10749 }
10750 return success;
10751}
10752
10753static bool field_endmsg(void *closure, const void *hd, upb_status *status) {
10754 upb_descreader *r = closure;
10755 upb_fielddef *f = r->f;
10756 UPB_UNUSED(hd);
10757
10758 /* TODO: verify that all required fields were present. */
10759 UPB_ASSERT(upb_fielddef_number(f) != 0);
10760 UPB_ASSERT(upb_fielddef_name(f) != NULL);
10761 UPB_ASSERT((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));
10762
10763 if (r->default_string) {
10764 if (upb_fielddef_issubmsg(f)) {
10765 upb_status_seterrmsg(status, "Submessages cannot have defaults.");
10766 return false;
10767 }
10768 if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) {
10769 upb_fielddef_setdefaultcstr(f, r->default_string, NULL);
10770 } else {
10771 if (r->default_string && !parse_default(r->default_string, f)) {
10772 /* We don't worry too much about giving a great error message since the
10773 * compiler should have ensured this was correct. */
10774 upb_status_seterrmsg(status, "Error converting default value.");
10775 return false;
10776 }
10777 }
10778 }
10779 return true;
10780}
10781
10782static bool field_onlazy(void *closure, const void *hd, bool val) {
10783 upb_descreader *r = closure;
10784 UPB_UNUSED(hd);
10785
10786 upb_fielddef_setlazy(r->f, val);
10787 return true;
10788}
10789
10790static bool field_onpacked(void *closure, const void *hd, bool val) {
10791 upb_descreader *r = closure;
10792 UPB_UNUSED(hd);
10793
10794 upb_fielddef_setpacked(r->f, val);
10795 return true;
10796}
10797
10798static bool field_ontype(void *closure, const void *hd, int32_t val) {
10799 upb_descreader *r = closure;
10800 UPB_UNUSED(hd);
10801
10802 upb_fielddef_setdescriptortype(r->f, val);
10803 return true;
10804}
10805
10806static bool field_onlabel(void *closure, const void *hd, int32_t val) {
10807 upb_descreader *r = closure;
10808 UPB_UNUSED(hd);
10809
10810 upb_fielddef_setlabel(r->f, val);
10811 return true;
10812}
10813
10814static bool field_onnumber(void *closure, const void *hd, int32_t val) {
10815 upb_descreader *r = closure;
10816 bool ok;
10817 UPB_UNUSED(hd);
10818
10819 ok = upb_fielddef_setnumber(r->f, val, NULL);
10820 UPB_ASSERT(ok);
10821 return true;
10822}
10823
10824static size_t field_onname(void *closure, const void *hd, const char *buf,
10825 size_t n, const upb_bufhandle *handle) {
10826 upb_descreader *r = closure;
10827 char *name = upb_gstrndup(buf, n);
10828 UPB_UNUSED(hd);
10829 UPB_UNUSED(handle);
10830
10831 /* XXX: see comment at the top of the file. */
10832 upb_fielddef_setname(r->f, name, NULL);
10833 upb_gfree(name);
10834 return n;
10835}
10836
10837static size_t field_ontypename(void *closure, const void *hd, const char *buf,
10838 size_t n, const upb_bufhandle *handle) {
10839 upb_descreader *r = closure;
10840 char *name = upb_gstrndup(buf, n);
10841 UPB_UNUSED(hd);
10842 UPB_UNUSED(handle);
10843
10844 /* XXX: see comment at the top of the file. */
10845 upb_fielddef_setsubdefname(r->f, name, NULL);
10846 upb_gfree(name);
10847 return n;
10848}
10849
10850static size_t field_onextendee(void *closure, const void *hd, const char *buf,
10851 size_t n, const upb_bufhandle *handle) {
10852 upb_descreader *r = closure;
10853 char *name = upb_gstrndup(buf, n);
10854 UPB_UNUSED(hd);
10855 UPB_UNUSED(handle);
10856
10857 /* XXX: see comment at the top of the file. */
10858 upb_fielddef_setcontainingtypename(r->f, name, NULL);
10859 upb_gfree(name);
10860 return n;
10861}
10862
10863static size_t field_ondefaultval(void *closure, const void *hd, const char *buf,
10864 size_t n, const upb_bufhandle *handle) {
10865 upb_descreader *r = closure;
10866 UPB_UNUSED(hd);
10867 UPB_UNUSED(handle);
10868
10869 /* Have to convert from string to the correct type, but we might not know the
10870 * type yet, so we save it as a string until the end of the field.
10871 * XXX: see comment at the top of the file. */
10872 upb_gfree(r->default_string);
10873 r->default_string = upb_gstrndup(buf, n);
10874 return n;
10875}
10876
10877static bool field_ononeofindex(void *closure, const void *hd, int32_t index) {
10878 upb_descreader *r = closure;
10879 upb_oneofdef *o = upb_descreader_getoneof(r, index);
10880 bool ok = upb_oneofdef_addfield(o, r->f, &r->f, NULL);
10881 UPB_UNUSED(hd);
10882
10883 UPB_ASSERT(ok);
10884 return true;
10885}
10886
10887/** Handlers for google.protobuf.OneofDescriptorProto. ************************/
10888
10889static size_t oneof_name(void *closure, const void *hd, const char *buf,
10890 size_t n, const upb_bufhandle *handle) {
10891 upb_descreader *r = closure;
10892 upb_descreader_frame *f = &r->stack[r->stack_len-1];
10893 upb_oneofdef *o = upb_descreader_getoneof(r, f->oneof_index++);
10894 char *name_null_terminated = upb_gstrndup(buf, n);
10895 bool ok = upb_oneofdef_setname(o, name_null_terminated, NULL);
10896 UPB_UNUSED(hd);
10897 UPB_UNUSED(handle);
10898
10899 UPB_ASSERT(ok);
10900 free(name_null_terminated);
10901 return n;
10902}
10903
10904/** Handlers for google.protobuf.DescriptorProto ******************************/
10905
10906static bool msg_start(void *closure, const void *hd) {
10907 upb_descreader *r = closure;
10908 UPB_UNUSED(hd);
10909
10910 upb_descreader_startcontainer(r);
10911 return true;
10912}
10913
10914static bool msg_end(void *closure, const void *hd, upb_status *status) {
10915 upb_descreader *r = closure;
10916 upb_msgdef *m = upb_descreader_top(r);
10917 UPB_UNUSED(hd);
10918
10919 if(!upb_def_fullname(upb_msgdef_upcast_mutable(m))) {
10920 upb_status_seterrmsg(status, "Encountered message with no name.");
10921 return false;
10922 }
10923 return upb_descreader_endcontainer(r);
10924}
10925
10926static size_t msg_name(void *closure, const void *hd, const char *buf,
10927 size_t n, const upb_bufhandle *handle) {
10928 upb_descreader *r = closure;
10929 upb_msgdef *m = upb_descreader_top(r);
10930 /* XXX: see comment at the top of the file. */
10931 char *name = upb_gstrndup(buf, n);
10932 UPB_UNUSED(hd);
10933 UPB_UNUSED(handle);
10934
10935 upb_def_setfullname(upb_msgdef_upcast_mutable(m), name, NULL);
10936 upb_descreader_setscopename(r, name); /* Passes ownership of name. */
10937 return n;
10938}
10939
10940static void *msg_startmsg(void *closure, const void *hd) {
10941 upb_descreader *r = closure;
10942 upb_msgdef *m = upb_msgdef_new(&m);
10943 bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
10944 UPB_UNUSED(hd);
10945 UPB_ASSERT(ok);
10946 return r;
10947}
10948
10949static void *msg_startext(void *closure, const void *hd) {
10950 upb_descreader *r = closure;
10951 upb_fielddef *f = upb_fielddef_new(&f);
10952 bool ok = upb_filedef_addext(r->file, f, &f, NULL);
10953 UPB_UNUSED(hd);
10954 UPB_ASSERT(ok);
10955 return r;
10956}
10957
10958static void *msg_startfield(void *closure, const void *hd) {
10959 upb_descreader *r = closure;
10960 r->f = upb_fielddef_new(&r->f);
10961 /* We can't add the new field to the message until its name/number are
10962 * filled in. */
10963 UPB_UNUSED(hd);
10964 return r;
10965}
10966
10967static bool msg_endfield(void *closure, const void *hd) {
10968 upb_descreader *r = closure;
10969 upb_msgdef *m = upb_descreader_top(r);
10970 bool ok;
10971 UPB_UNUSED(hd);
10972
10973 /* Oneof fields are added to the msgdef through their oneof, so don't need to
10974 * be added here. */
10975 if (upb_fielddef_containingoneof(r->f) == NULL) {
10976 ok = upb_msgdef_addfield(m, r->f, &r->f, NULL);
10977 UPB_ASSERT(ok);
10978 }
10979 r->f = NULL;
10980 return true;
10981}
10982
10983static bool msg_onmapentry(void *closure, const void *hd, bool mapentry) {
10984 upb_descreader *r = closure;
10985 upb_msgdef *m = upb_descreader_top(r);
10986 UPB_UNUSED(hd);
10987
10988 upb_msgdef_setmapentry(m, mapentry);
10989 r->f = NULL;
10990 return true;
10991}
10992
10993
10994
10995/** Code to register handlers *************************************************/
10996
10997#define F(msg, field) upbdefs_google_protobuf_ ## msg ## _f_ ## field(m)
10998
10999static void reghandlers(const void *closure, upb_handlers *h) {
11000 const upb_msgdef *m = upb_handlers_msgdef(h);
11001 UPB_UNUSED(closure);
11002
11003 if (upbdefs_google_protobuf_FileDescriptorSet_is(m)) {
11004 upb_handlers_setstartsubmsg(h, F(FileDescriptorSet, file),
11005 &fileset_startfile, NULL);
11006 } else if (upbdefs_google_protobuf_DescriptorProto_is(m)) {
11007 upb_handlers_setstartmsg(h, &msg_start, NULL);
11008 upb_handlers_setendmsg(h, &msg_end, NULL);
11009 upb_handlers_setstring(h, F(DescriptorProto, name), &msg_name, NULL);
11010 upb_handlers_setstartsubmsg(h, F(DescriptorProto, extension), &msg_startext,
11011 NULL);
11012 upb_handlers_setstartsubmsg(h, F(DescriptorProto, nested_type),
11013 &msg_startmsg, NULL);
11014 upb_handlers_setstartsubmsg(h, F(DescriptorProto, field),
11015 &msg_startfield, NULL);
11016 upb_handlers_setendsubmsg(h, F(DescriptorProto, field),
11017 &msg_endfield, NULL);
11018 upb_handlers_setstartsubmsg(h, F(DescriptorProto, enum_type),
11019 &file_startenum, NULL);
11020 } else if (upbdefs_google_protobuf_FileDescriptorProto_is(m)) {
11021 upb_handlers_setstartmsg(h, &file_start, NULL);
11022 upb_handlers_setendmsg(h, &file_end, NULL);
11023 upb_handlers_setstring(h, F(FileDescriptorProto, name), &file_onname,
11024 NULL);
11025 upb_handlers_setstring(h, F(FileDescriptorProto, package), &file_onpackage,
11026 NULL);
11027 upb_handlers_setstring(h, F(FileDescriptorProto, syntax), &file_onsyntax,
11028 NULL);
11029 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, message_type),
11030 &file_startmsg, NULL);
11031 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, enum_type),
11032 &file_startenum, NULL);
11033 upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension),
11034 &file_startext, NULL);
11035 upb_handlers_setstring(h, F(FileDescriptorProto, dependency),
11036 &file_ondep, NULL);
11037 } else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) {
11038 upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
11039 upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
11040 upb_handlers_setstring(h, F(EnumValueDescriptorProto, name), &enumval_onname, NULL);
11041 upb_handlers_setint32(h, F(EnumValueDescriptorProto, number), &enumval_onnumber,
11042 NULL);
11043 } else if (upbdefs_google_protobuf_EnumDescriptorProto_is(m)) {
11044 upb_handlers_setendmsg(h, &enum_endmsg, NULL);
11045 upb_handlers_setstring(h, F(EnumDescriptorProto, name), &enum_onname, NULL);
11046 } else if (upbdefs_google_protobuf_FieldDescriptorProto_is(m)) {
11047 upb_handlers_setstartmsg(h, &field_startmsg, NULL);
11048 upb_handlers_setendmsg(h, &field_endmsg, NULL);
11049 upb_handlers_setint32(h, F(FieldDescriptorProto, type), &field_ontype,
11050 NULL);
11051 upb_handlers_setint32(h, F(FieldDescriptorProto, label), &field_onlabel,
11052 NULL);
11053 upb_handlers_setint32(h, F(FieldDescriptorProto, number), &field_onnumber,
11054 NULL);
11055 upb_handlers_setstring(h, F(FieldDescriptorProto, name), &field_onname,
11056 NULL);
11057 upb_handlers_setstring(h, F(FieldDescriptorProto, type_name),
11058 &field_ontypename, NULL);
11059 upb_handlers_setstring(h, F(FieldDescriptorProto, extendee),
11060 &field_onextendee, NULL);
11061 upb_handlers_setstring(h, F(FieldDescriptorProto, default_value),
11062 &field_ondefaultval, NULL);
11063 upb_handlers_setint32(h, F(FieldDescriptorProto, oneof_index),
11064 &field_ononeofindex, NULL);
11065 } else if (upbdefs_google_protobuf_OneofDescriptorProto_is(m)) {
11066 upb_handlers_setstring(h, F(OneofDescriptorProto, name), &oneof_name, NULL);
11067 } else if (upbdefs_google_protobuf_FieldOptions_is(m)) {
11068 upb_handlers_setbool(h, F(FieldOptions, lazy), &field_onlazy, NULL);
11069 upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL);
11070 } else if (upbdefs_google_protobuf_MessageOptions_is(m)) {
11071 upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL);
11072 } else if (upbdefs_google_protobuf_FileOptions_is(m)) {
11073 upb_handlers_setstring(h, F(FileOptions, php_class_prefix),
11074 &file_onphpprefix, NULL);
11075 upb_handlers_setstartstr(h, F(FileOptions, php_namespace),
11076 &file_startphpnamespace, NULL);
11077 upb_handlers_setstring(h, F(FileOptions, php_namespace),
11078 &file_onphpnamespace, NULL);
11079 }
11080
11081 UPB_ASSERT(upb_ok(upb_handlers_status(h)));
11082}
11083
11084#undef F
11085
11086void descreader_cleanup(void *_r) {
11087 upb_descreader *r = _r;
11088 size_t i;
11089
11090 for (i = 0; i < upb_descreader_filecount(r); i++) {
11091 upb_filedef_unref(upb_descreader_file(r, i), &r->files);
11092 }
11093
11094 upb_gfree(r->name);
11095 upb_inttable_uninit(&r->files);
11096 upb_strtable_uninit(&r->files_by_name);
11097 upb_inttable_uninit(&r->oneofs);
11098 upb_gfree(r->default_string);
11099 while (r->stack_len > 0) {
11100 upb_descreader_frame *f = &r->stack[--r->stack_len];
11101 upb_gfree(f->name);
11102 }
11103}
11104
11105
11106/* Public API ****************************************************************/
11107
11108upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
11109 upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader));
11110 if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) {
11111 return NULL;
11112 }
11113
11114 upb_inttable_init(&r->files, UPB_CTYPE_PTR);
11115 upb_strtable_init(&r->files_by_name, UPB_CTYPE_PTR);
11116 upb_inttable_init(&r->oneofs, UPB_CTYPE_PTR);
11117 upb_sink_reset(upb_descreader_input(r), h, r);
11118 r->stack_len = 0;
11119 r->name = NULL;
11120 r->default_string = NULL;
11121
11122 return r;
11123}
11124
11125size_t upb_descreader_filecount(const upb_descreader *r) {
11126 return upb_inttable_count(&r->files);
11127}
11128
11129upb_filedef *upb_descreader_file(const upb_descreader *r, size_t i) {
11130 upb_value v;
11131 if (upb_inttable_lookup(&r->files, i, &v)) {
11132 return upb_value_getptr(v);
11133 } else {
11134 return NULL;
11135 }
11136}
11137
11138upb_sink *upb_descreader_input(upb_descreader *r) {
11139 return &r->sink;
11140}
11141
11142const upb_handlers *upb_descreader_newhandlers(const void *owner) {
11143 const upb_msgdef *m = upbdefs_google_protobuf_FileDescriptorSet_get(&m);
11144 const upb_handlers *h = upb_handlers_newfrozen(m, owner, reghandlers, NULL);
11145 upb_msgdef_unref(m, &m);
11146 return h;
11147}
11148/*
11149** protobuf decoder bytecode compiler
11150**
11151** Code to compile a upb::Handlers into bytecode for decoding a protobuf
11152** according to that specific schema and destination handlers.
11153**
11154** Compiling to bytecode is always the first step. If we are using the
11155** interpreted decoder we leave it as bytecode and interpret that. If we are
11156** using a JIT decoder we use a code generator to turn the bytecode into native
11157** code, LLVM IR, etc.
11158**
11159** Bytecode definition is in decoder.int.h.
11160*/
11161
11162#include <stdarg.h>
11163
11164#ifdef UPB_DUMP_BYTECODE
11165#include <stdio.h>
11166#endif
11167
11168#define MAXLABEL 5
11169#define EMPTYLABEL -1
11170
11171/* mgroup *********************************************************************/
11172
11173static void freegroup(upb_refcounted *r) {
11174 mgroup *g = (mgroup*)r;
11175 upb_inttable_uninit(&g->methods);
11176#ifdef UPB_USE_JIT_X64
11177 upb_pbdecoder_freejit(g);
11178#endif
11179 upb_gfree(g->bytecode);
11180 upb_gfree(g);
11181}
11182
11183static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
11184 void *closure) {
11185 const mgroup *g = (const mgroup*)r;
11186 upb_inttable_iter i;
11187 upb_inttable_begin(&i, &g->methods);
11188 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
11189 upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
11190 visit(r, upb_pbdecodermethod_upcast(method), closure);
11191 }
11192}
11193
11194mgroup *newgroup(const void *owner) {
11195 mgroup *g = upb_gmalloc(sizeof(*g));
11196 static const struct upb_refcounted_vtbl vtbl = {visitgroup, freegroup};
11197 upb_refcounted_init(mgroup_upcast_mutable(g), &vtbl, owner);
11198 upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
11199 g->bytecode = NULL;
11200 g->bytecode_end = NULL;
11201 return g;
11202}
11203
11204
11205/* upb_pbdecodermethod ********************************************************/
11206
11207static void freemethod(upb_refcounted *r) {
11208 upb_pbdecodermethod *method = (upb_pbdecodermethod*)r;
11209
11210 if (method->dest_handlers_) {
11211 upb_handlers_unref(method->dest_handlers_, method);
11212 }
11213
11214 upb_inttable_uninit(&method->dispatch);
11215 upb_gfree(method);
11216}
11217
11218static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
11219 void *closure) {
11220 const upb_pbdecodermethod *m = (const upb_pbdecodermethod*)r;
11221 visit(r, m->group, closure);
11222}
11223
11224static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
11225 mgroup *group) {
11226 static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod};
11227 upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret));
11228 upb_refcounted_init(upb_pbdecodermethod_upcast_mutable(ret), &vtbl, &ret);
11229 upb_byteshandler_init(&ret->input_handler_);
11230
11231 /* The method references the group and vice-versa, in a circular reference. */
11232 upb_ref2(ret, group);
11233 upb_ref2(group, ret);
11234 upb_inttable_insertptr(&group->methods, dest_handlers, upb_value_ptr(ret));
11235 upb_pbdecodermethod_unref(ret, &ret);
11236
11237 ret->group = mgroup_upcast_mutable(group);
11238 ret->dest_handlers_ = dest_handlers;
11239 ret->is_native_ = false; /* If we JIT, it will update this later. */
11240 upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64);
11241
11242 if (ret->dest_handlers_) {
11243 upb_handlers_ref(ret->dest_handlers_, ret);
11244 }
11245 return ret;
11246}
11247
11248const upb_handlers *upb_pbdecodermethod_desthandlers(
11249 const upb_pbdecodermethod *m) {
11250 return m->dest_handlers_;
11251}
11252
11253const upb_byteshandler *upb_pbdecodermethod_inputhandler(
11254 const upb_pbdecodermethod *m) {
11255 return &m->input_handler_;
11256}
11257
11258bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m) {
11259 return m->is_native_;
11260}
11261
11262const upb_pbdecodermethod *upb_pbdecodermethod_new(
11263 const upb_pbdecodermethodopts *opts, const void *owner) {
11264 const upb_pbdecodermethod *ret;
11265 upb_pbcodecache cache;
11266
11267 upb_pbcodecache_init(&cache);
11268 ret = upb_pbcodecache_getdecodermethod(&cache, opts);
11269 upb_pbdecodermethod_ref(ret, owner);
11270 upb_pbcodecache_uninit(&cache);
11271 return ret;
11272}
11273
11274
11275/* bytecode compiler **********************************************************/
11276
11277/* Data used only at compilation time. */
11278typedef struct {
11279 mgroup *group;
11280
11281 uint32_t *pc;
11282 int fwd_labels[MAXLABEL];
11283 int back_labels[MAXLABEL];
11284
11285 /* For fields marked "lazy", parse them lazily or eagerly? */
11286 bool lazy;
11287} compiler;
11288
11289static compiler *newcompiler(mgroup *group, bool lazy) {
11290 compiler *ret = upb_gmalloc(sizeof(*ret));
11291 int i;
11292
11293 ret->group = group;
11294 ret->lazy = lazy;
11295 for (i = 0; i < MAXLABEL; i++) {
11296 ret->fwd_labels[i] = EMPTYLABEL;
11297 ret->back_labels[i] = EMPTYLABEL;
11298 }
11299 return ret;
11300}
11301
11302static void freecompiler(compiler *c) {
11303 upb_gfree(c);
11304}
11305
11306const size_t ptr_words = sizeof(void*) / sizeof(uint32_t);
11307
11308/* How many words an instruction is. */
11309static int instruction_len(uint32_t instr) {
11310 switch (getop(instr)) {
11311 case OP_SETDISPATCH: return 1 + ptr_words;
11312 case OP_TAGN: return 3;
11313 case OP_SETBIGGROUPNUM: return 2;
11314 default: return 1;
11315 }
11316}
11317
11318bool op_has_longofs(int32_t instruction) {
11319 switch (getop(instruction)) {
11320 case OP_CALL:
11321 case OP_BRANCH:
11322 case OP_CHECKDELIM:
11323 return true;
11324 /* The "tag" instructions only have 8 bytes available for the jump target,
11325 * but that is ok because these opcodes only require short jumps. */
11326 case OP_TAG1:
11327 case OP_TAG2:
11328 case OP_TAGN:
11329 return false;
11330 default:
11331 UPB_ASSERT(false);
11332 return false;
11333 }
11334}
11335
11336static int32_t getofs(uint32_t instruction) {
11337 if (op_has_longofs(instruction)) {
11338 return (int32_t)instruction >> 8;
11339 } else {
11340 return (int8_t)(instruction >> 8);
11341 }
11342}
11343
11344static void setofs(uint32_t *instruction, int32_t ofs) {
11345 if (op_has_longofs(*instruction)) {
11346 *instruction = getop(*instruction) | ofs << 8;
11347 } else {
11348 *instruction = (*instruction & ~0xff00) | ((ofs & 0xff) << 8);
11349 }
11350 UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */
11351}
11352
11353static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; }
11354
11355/* Defines a local label at the current PC location. All previous forward
11356 * references are updated to point to this location. The location is noted
11357 * for any future backward references. */
11358static void label(compiler *c, unsigned int label) {
11359 int val;
11360 uint32_t *codep;
11361
11362 UPB_ASSERT(label < MAXLABEL);
11363 val = c->fwd_labels[label];
11364 codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val;
11365 while (codep) {
11366 int ofs = getofs(*codep);
11367 setofs(codep, c->pc - codep - instruction_len(*codep));
11368 codep = ofs ? codep + ofs : NULL;
11369 }
11370 c->fwd_labels[label] = EMPTYLABEL;
11371 c->back_labels[label] = pcofs(c);
11372}
11373
11374/* Creates a reference to a numbered label; either a forward reference
11375 * (positive arg) or backward reference (negative arg). For forward references
11376 * the value returned now is actually a "next" pointer into a linked list of all
11377 * instructions that use this label and will be patched later when the label is
11378 * defined with label().
11379 *
11380 * The returned value is the offset that should be written into the instruction.
11381 */
11382static int32_t labelref(compiler *c, int label) {
11383 UPB_ASSERT(label < MAXLABEL);
11384 if (label == LABEL_DISPATCH) {
11385 /* No resolving required. */
11386 return 0;
11387 } else if (label < 0) {
11388 /* Backward local label. Relative to the next instruction. */
11389 uint32_t from = (c->pc + 1) - c->group->bytecode;
11390 return c->back_labels[-label] - from;
11391 } else {
11392 /* Forward local label: prepend to (possibly-empty) linked list. */
11393 int *lptr = &c->fwd_labels[label];
11394 int32_t ret = (*lptr == EMPTYLABEL) ? 0 : *lptr - pcofs(c);
11395 *lptr = pcofs(c);
11396 return ret;
11397 }
11398}
11399
11400static void put32(compiler *c, uint32_t v) {
11401 mgroup *g = c->group;
11402 if (c->pc == g->bytecode_end) {
11403 int ofs = pcofs(c);
11404 size_t oldsize = g->bytecode_end - g->bytecode;
11405 size_t newsize = UPB_MAX(oldsize * 2, 64);
11406 /* TODO(haberman): handle OOM. */
11407 g->bytecode = upb_grealloc(g->bytecode, oldsize * sizeof(uint32_t),
11408 newsize * sizeof(uint32_t));
11409 g->bytecode_end = g->bytecode + newsize;
11410 c->pc = g->bytecode + ofs;
11411 }
11412 *c->pc++ = v;
11413}
11414
11415static void putop(compiler *c, int op, ...) {
11416 va_list ap;
11417 va_start(ap, op);
11418
11419 switch (op) {
11420 case OP_SETDISPATCH: {
11421 uintptr_t ptr = (uintptr_t)va_arg(ap, void*);
11422 put32(c, OP_SETDISPATCH);
11423 put32(c, ptr);
11424 if (sizeof(uintptr_t) > sizeof(uint32_t))
11425 put32(c, (uint64_t)ptr >> 32);
11426 break;
11427 }
11428 case OP_STARTMSG:
11429 case OP_ENDMSG:
11430 case OP_PUSHLENDELIM:
11431 case OP_POP:
11432 case OP_SETDELIM:
11433 case OP_HALT:
11434 case OP_RET:
11435 case OP_DISPATCH:
11436 put32(c, op);
11437 break;
11438 case OP_PARSE_DOUBLE:
11439 case OP_PARSE_FLOAT:
11440 case OP_PARSE_INT64:
11441 case OP_PARSE_UINT64:
11442 case OP_PARSE_INT32:
11443 case OP_PARSE_FIXED64:
11444 case OP_PARSE_FIXED32:
11445 case OP_PARSE_BOOL:
11446 case OP_PARSE_UINT32:
11447 case OP_PARSE_SFIXED32:
11448 case OP_PARSE_SFIXED64:
11449 case OP_PARSE_SINT32:
11450 case OP_PARSE_SINT64:
11451 case OP_STARTSEQ:
11452 case OP_ENDSEQ:
11453 case OP_STARTSUBMSG:
11454 case OP_ENDSUBMSG:
11455 case OP_STARTSTR:
11456 case OP_STRING:
11457 case OP_ENDSTR:
11458 case OP_PUSHTAGDELIM:
11459 put32(c, op | va_arg(ap, upb_selector_t) << 8);
11460 break;
11461 case OP_SETBIGGROUPNUM:
11462 put32(c, op);
11463 put32(c, va_arg(ap, int));
11464 break;
11465 case OP_CALL: {
11466 const upb_pbdecodermethod *method = va_arg(ap, upb_pbdecodermethod *);
11467 put32(c, op | (method->code_base.ofs - (pcofs(c) + 1)) << 8);
11468 break;
11469 }
11470 case OP_CHECKDELIM:
11471 case OP_BRANCH: {
11472 uint32_t instruction = op;
11473 int label = va_arg(ap, int);
11474 setofs(&instruction, labelref(c, label));
11475 put32(c, instruction);
11476 break;
11477 }
11478 case OP_TAG1:
11479 case OP_TAG2: {
11480 int label = va_arg(ap, int);
11481 uint64_t tag = va_arg(ap, uint64_t);
11482 uint32_t instruction = op | (tag << 16);
11483 UPB_ASSERT(tag <= 0xffff);
11484 setofs(&instruction, labelref(c, label));
11485 put32(c, instruction);
11486 break;
11487 }
11488 case OP_TAGN: {
11489 int label = va_arg(ap, int);
11490 uint64_t tag = va_arg(ap, uint64_t);
11491 uint32_t instruction = op | (upb_value_size(tag) << 16);
11492 setofs(&instruction, labelref(c, label));
11493 put32(c, instruction);
11494 put32(c, tag);
11495 put32(c, tag >> 32);
11496 break;
11497 }
11498 }
11499
11500 va_end(ap);
11501}
11502
11503#if defined(UPB_USE_JIT_X64) || defined(UPB_DUMP_BYTECODE)
11504
11505const char *upb_pbdecoder_getopname(unsigned int op) {
11506#define QUOTE(x) #x
11507#define EXPAND_AND_QUOTE(x) QUOTE(x)
11508#define OPNAME(x) OP_##x
11509#define OP(x) case OPNAME(x): return EXPAND_AND_QUOTE(OPNAME(x));
11510#define T(x) OP(PARSE_##x)
11511 /* Keep in sync with list in decoder.int.h. */
11512 switch ((opcode)op) {
11513 T(DOUBLE) T(FLOAT) T(INT64) T(UINT64) T(INT32) T(FIXED64) T(FIXED32)
11514 T(BOOL) T(UINT32) T(SFIXED32) T(SFIXED64) T(SINT32) T(SINT64)
11515 OP(STARTMSG) OP(ENDMSG) OP(STARTSEQ) OP(ENDSEQ) OP(STARTSUBMSG)
11516 OP(ENDSUBMSG) OP(STARTSTR) OP(STRING) OP(ENDSTR) OP(CALL) OP(RET)
11517 OP(PUSHLENDELIM) OP(PUSHTAGDELIM) OP(SETDELIM) OP(CHECKDELIM)
11518 OP(BRANCH) OP(TAG1) OP(TAG2) OP(TAGN) OP(SETDISPATCH) OP(POP)
11519 OP(SETBIGGROUPNUM) OP(DISPATCH) OP(HALT)
11520 }
11521 return "<unknown op>";
11522#undef OP
11523#undef T
11524}
11525
11526#endif
11527
11528#ifdef UPB_DUMP_BYTECODE
11529
11530static void dumpbc(uint32_t *p, uint32_t *end, FILE *f) {
11531
11532 uint32_t *begin = p;
11533
11534 while (p < end) {
11535 fprintf(f, "%p %8tx", p, p - begin);
11536 uint32_t instr = *p++;
11537 uint8_t op = getop(instr);
11538 fprintf(f, " %s", upb_pbdecoder_getopname(op));
11539 switch ((opcode)op) {
11540 case OP_SETDISPATCH: {
11541 const upb_inttable *dispatch;
11542 memcpy(&dispatch, p, sizeof(void*));
11543 p += ptr_words;
11544 const upb_pbdecodermethod *method =
11545 (void *)((char *)dispatch -
11546 offsetof(upb_pbdecodermethod, dispatch));
11547 fprintf(f, " %s", upb_msgdef_fullname(
11548 upb_handlers_msgdef(method->dest_handlers_)));
11549 break;
11550 }
11551 case OP_DISPATCH:
11552 case OP_STARTMSG:
11553 case OP_ENDMSG:
11554 case OP_PUSHLENDELIM:
11555 case OP_POP:
11556 case OP_SETDELIM:
11557 case OP_HALT:
11558 case OP_RET:
11559 break;
11560 case OP_PARSE_DOUBLE:
11561 case OP_PARSE_FLOAT:
11562 case OP_PARSE_INT64:
11563 case OP_PARSE_UINT64:
11564 case OP_PARSE_INT32:
11565 case OP_PARSE_FIXED64:
11566 case OP_PARSE_FIXED32:
11567 case OP_PARSE_BOOL:
11568 case OP_PARSE_UINT32:
11569 case OP_PARSE_SFIXED32:
11570 case OP_PARSE_SFIXED64:
11571 case OP_PARSE_SINT32:
11572 case OP_PARSE_SINT64:
11573 case OP_STARTSEQ:
11574 case OP_ENDSEQ:
11575 case OP_STARTSUBMSG:
11576 case OP_ENDSUBMSG:
11577 case OP_STARTSTR:
11578 case OP_STRING:
11579 case OP_ENDSTR:
11580 case OP_PUSHTAGDELIM:
11581 fprintf(f, " %d", instr >> 8);
11582 break;
11583 case OP_SETBIGGROUPNUM:
11584 fprintf(f, " %d", *p++);
11585 break;
11586 case OP_CHECKDELIM:
11587 case OP_CALL:
11588 case OP_BRANCH:
11589 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
11590 break;
11591 case OP_TAG1:
11592 case OP_TAG2: {
11593 fprintf(f, " tag:0x%x", instr >> 16);
11594 if (getofs(instr)) {
11595 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
11596 }
11597 break;
11598 }
11599 case OP_TAGN: {
11600 uint64_t tag = *p++;
11601 tag |= (uint64_t)*p++ << 32;
11602 fprintf(f, " tag:0x%llx", (long long)tag);
11603 fprintf(f, " n:%d", instr >> 16);
11604 if (getofs(instr)) {
11605 fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
11606 }
11607 break;
11608 }
11609 }
11610 fputs("\n", f);
11611 }
11612}
11613
11614#endif
11615
11616static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type) {
11617 uint32_t tag = (upb_fielddef_number(f) << 3) | wire_type;
11618 uint64_t encoded_tag = upb_vencode32(tag);
11619 /* No tag should be greater than 5 bytes. */
11620 UPB_ASSERT(encoded_tag <= 0xffffffffff);
11621 return encoded_tag;
11622}
11623
11624static void putchecktag(compiler *c, const upb_fielddef *f,
11625 int wire_type, int dest) {
11626 uint64_t tag = get_encoded_tag(f, wire_type);
11627 switch (upb_value_size(tag)) {
11628 case 1:
11629 putop(c, OP_TAG1, dest, tag);
11630 break;
11631 case 2:
11632 putop(c, OP_TAG2, dest, tag);
11633 break;
11634 default:
11635 putop(c, OP_TAGN, dest, tag);
11636 break;
11637 }
11638}
11639
11640static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
11641 upb_selector_t selector;
11642 bool ok = upb_handlers_getselector(f, type, &selector);
11643 UPB_ASSERT(ok);
11644 return selector;
11645}
11646
11647/* Takes an existing, primary dispatch table entry and repacks it with a
11648 * different alternate wire type. Called when we are inserting a secondary
11649 * dispatch table entry for an alternate wire type. */
11650static uint64_t repack(uint64_t dispatch, int new_wt2) {
11651 uint64_t ofs;
11652 uint8_t wt1;
11653 uint8_t old_wt2;
11654 upb_pbdecoder_unpackdispatch(dispatch, &ofs, &wt1, &old_wt2);
11655 UPB_ASSERT(old_wt2 == NO_WIRE_TYPE); /* wt2 should not be set yet. */
11656 return upb_pbdecoder_packdispatch(ofs, wt1, new_wt2);
11657}
11658
11659/* Marks the current bytecode position as the dispatch target for this message,
11660 * field, and wire type. */
11661static void dispatchtarget(compiler *c, upb_pbdecodermethod *method,
11662 const upb_fielddef *f, int wire_type) {
11663 /* Offset is relative to msg base. */
11664 uint64_t ofs = pcofs(c) - method->code_base.ofs;
11665 uint32_t fn = upb_fielddef_number(f);
11666 upb_inttable *d = &method->dispatch;
11667 upb_value v;
11668 if (upb_inttable_remove(d, fn, &v)) {
11669 /* TODO: prioritize based on packed setting in .proto file. */
11670 uint64_t repacked = repack(upb_value_getuint64(v), wire_type);
11671 upb_inttable_insert(d, fn, upb_value_uint64(repacked));
11672 upb_inttable_insert(d, fn + UPB_MAX_FIELDNUMBER, upb_value_uint64(ofs));
11673 } else {
11674 uint64_t val = upb_pbdecoder_packdispatch(ofs, wire_type, NO_WIRE_TYPE);
11675 upb_inttable_insert(d, fn, upb_value_uint64(val));
11676 }
11677}
11678
11679static void putpush(compiler *c, const upb_fielddef *f) {
11680 if (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE) {
11681 putop(c, OP_PUSHLENDELIM);
11682 } else {
11683 uint32_t fn = upb_fielddef_number(f);
11684 if (fn >= 1 << 24) {
11685 putop(c, OP_PUSHTAGDELIM, 0);
11686 putop(c, OP_SETBIGGROUPNUM, fn);
11687 } else {
11688 putop(c, OP_PUSHTAGDELIM, fn);
11689 }
11690 }
11691}
11692
11693static upb_pbdecodermethod *find_submethod(const compiler *c,
11694 const upb_pbdecodermethod *method,
11695 const upb_fielddef *f) {
11696 const upb_handlers *sub =
11697 upb_handlers_getsubhandlers(method->dest_handlers_, f);
11698 upb_value v;
11699 return upb_inttable_lookupptr(&c->group->methods, sub, &v)
11700 ? upb_value_getptr(v)
11701 : NULL;
11702}
11703
11704static void putsel(compiler *c, opcode op, upb_selector_t sel,
11705 const upb_handlers *h) {
11706 if (upb_handlers_gethandler(h, sel)) {
11707 putop(c, op, sel);
11708 }
11709}
11710
11711/* Puts an opcode to call a callback, but only if a callback actually exists for
11712 * this field and handler type. */
11713static void maybeput(compiler *c, opcode op, const upb_handlers *h,
11714 const upb_fielddef *f, upb_handlertype_t type) {
11715 putsel(c, op, getsel(f, type), h);
11716}
11717
11718static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) {
11719 if (!upb_fielddef_lazy(f))
11720 return false;
11721
11722 return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR)) ||
11723 upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING)) ||
11724 upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR));
11725}
11726
11727
11728/* bytecode compiler code generation ******************************************/
11729
11730/* Symbolic names for our local labels. */
11731#define LABEL_LOOPSTART 1 /* Top of a repeated field loop. */
11732#define LABEL_LOOPBREAK 2 /* To jump out of a repeated loop */
11733#define LABEL_FIELD 3 /* Jump backward to find the most recent field. */
11734#define LABEL_ENDMSG 4 /* To reach the OP_ENDMSG instr for this msg. */
11735
11736/* Generates bytecode to parse a single non-lazy message field. */
11737static void generate_msgfield(compiler *c, const upb_fielddef *f,
11738 upb_pbdecodermethod *method) {
11739 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
11740 const upb_pbdecodermethod *sub_m = find_submethod(c, method, f);
11741 int wire_type;
11742
11743 if (!sub_m) {
11744 /* Don't emit any code for this field at all; it will be parsed as an
11745 * unknown field.
11746 *
11747 * TODO(haberman): we should change this to parse it as a string field
11748 * instead. It will probably be faster, but more importantly, once we
11749 * start vending unknown fields, a field shouldn't be treated as unknown
11750 * just because it doesn't have subhandlers registered. */
11751 return;
11752 }
11753
11754 label(c, LABEL_FIELD);
11755
11756 wire_type =
11757 (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE)
11758 ? UPB_WIRE_TYPE_DELIMITED
11759 : UPB_WIRE_TYPE_START_GROUP;
11760
11761 if (upb_fielddef_isseq(f)) {
11762 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11763 putchecktag(c, f, wire_type, LABEL_DISPATCH);
11764 dispatchtarget(c, method, f, wire_type);
11765 putop(c, OP_PUSHTAGDELIM, 0);
11766 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
11767 label(c, LABEL_LOOPSTART);
11768 putpush(c, f);
11769 putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
11770 putop(c, OP_CALL, sub_m);
11771 putop(c, OP_POP);
11772 maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
11773 if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
11774 putop(c, OP_SETDELIM);
11775 }
11776 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
11777 putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
11778 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
11779 label(c, LABEL_LOOPBREAK);
11780 putop(c, OP_POP);
11781 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
11782 } else {
11783 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11784 putchecktag(c, f, wire_type, LABEL_DISPATCH);
11785 dispatchtarget(c, method, f, wire_type);
11786 putpush(c, f);
11787 putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
11788 putop(c, OP_CALL, sub_m);
11789 putop(c, OP_POP);
11790 maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
11791 if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
11792 putop(c, OP_SETDELIM);
11793 }
11794 }
11795}
11796
11797/* Generates bytecode to parse a single string or lazy submessage field. */
11798static void generate_delimfield(compiler *c, const upb_fielddef *f,
11799 upb_pbdecodermethod *method) {
11800 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
11801
11802 label(c, LABEL_FIELD);
11803 if (upb_fielddef_isseq(f)) {
11804 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11805 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
11806 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
11807 putop(c, OP_PUSHTAGDELIM, 0);
11808 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
11809 label(c, LABEL_LOOPSTART);
11810 putop(c, OP_PUSHLENDELIM);
11811 putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
11812 /* Need to emit even if no handler to skip past the string. */
11813 putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
11814 putop(c, OP_POP);
11815 maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
11816 putop(c, OP_SETDELIM);
11817 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
11818 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_LOOPBREAK);
11819 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
11820 label(c, LABEL_LOOPBREAK);
11821 putop(c, OP_POP);
11822 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
11823 } else {
11824 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11825 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
11826 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
11827 putop(c, OP_PUSHLENDELIM);
11828 putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
11829 putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
11830 putop(c, OP_POP);
11831 maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
11832 putop(c, OP_SETDELIM);
11833 }
11834}
11835
11836/* Generates bytecode to parse a single primitive field. */
11837static void generate_primitivefield(compiler *c, const upb_fielddef *f,
11838 upb_pbdecodermethod *method) {
11839 const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
11840 upb_descriptortype_t descriptor_type = upb_fielddef_descriptortype(f);
11841 opcode parse_type;
11842 upb_selector_t sel;
11843 int wire_type;
11844
11845 label(c, LABEL_FIELD);
11846
11847 /* From a decoding perspective, ENUM is the same as INT32. */
11848 if (descriptor_type == UPB_DESCRIPTOR_TYPE_ENUM)
11849 descriptor_type = UPB_DESCRIPTOR_TYPE_INT32;
11850
11851 parse_type = (opcode)descriptor_type;
11852
11853 /* TODO(haberman): generate packed or non-packed first depending on "packed"
11854 * setting in the fielddef. This will favor (in speed) whichever was
11855 * specified. */
11856
11857 UPB_ASSERT((int)parse_type >= 0 && parse_type <= OP_MAX);
11858 sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
11859 wire_type = upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
11860 if (upb_fielddef_isseq(f)) {
11861 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11862 putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
11863 dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
11864 putop(c, OP_PUSHLENDELIM);
11865 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Packed */
11866 label(c, LABEL_LOOPSTART);
11867 putop(c, parse_type, sel);
11868 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
11869 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
11870 dispatchtarget(c, method, f, wire_type);
11871 putop(c, OP_PUSHTAGDELIM, 0);
11872 putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Non-packed */
11873 label(c, LABEL_LOOPSTART);
11874 putop(c, parse_type, sel);
11875 putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
11876 putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
11877 putop(c, OP_BRANCH, -LABEL_LOOPSTART);
11878 label(c, LABEL_LOOPBREAK);
11879 putop(c, OP_POP); /* Packed and non-packed join. */
11880 maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
11881 putop(c, OP_SETDELIM); /* Could remove for non-packed by dup ENDSEQ. */
11882 } else {
11883 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11884 putchecktag(c, f, wire_type, LABEL_DISPATCH);
11885 dispatchtarget(c, method, f, wire_type);
11886 putop(c, parse_type, sel);
11887 }
11888}
11889
11890/* Adds bytecode for parsing the given message to the given decoderplan,
11891 * while adding all dispatch targets to this message's dispatch table. */
11892static void compile_method(compiler *c, upb_pbdecodermethod *method) {
11893 const upb_handlers *h;
11894 const upb_msgdef *md;
11895 uint32_t* start_pc;
11896 upb_msg_field_iter i;
11897 upb_value val;
11898
11899 UPB_ASSERT(method);
11900
11901 /* Clear all entries in the dispatch table. */
11902 upb_inttable_uninit(&method->dispatch);
11903 upb_inttable_init(&method->dispatch, UPB_CTYPE_UINT64);
11904
11905 h = upb_pbdecodermethod_desthandlers(method);
11906 md = upb_handlers_msgdef(h);
11907
11908 method->code_base.ofs = pcofs(c);
11909 putop(c, OP_SETDISPATCH, &method->dispatch);
11910 putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h);
11911 label(c, LABEL_FIELD);
11912 start_pc = c->pc;
11913 for(upb_msg_field_begin(&i, md);
11914 !upb_msg_field_done(&i);
11915 upb_msg_field_next(&i)) {
11916 const upb_fielddef *f = upb_msg_iter_field(&i);
11917 upb_fieldtype_t type = upb_fielddef_type(f);
11918
11919 if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) {
11920 generate_msgfield(c, f, method);
11921 } else if (type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES ||
11922 type == UPB_TYPE_MESSAGE) {
11923 generate_delimfield(c, f, method);
11924 } else {
11925 generate_primitivefield(c, f, method);
11926 }
11927 }
11928
11929 /* If there were no fields, or if no handlers were defined, we need to
11930 * generate a non-empty loop body so that we can at least dispatch for unknown
11931 * fields and check for the end of the message. */
11932 if (c->pc == start_pc) {
11933 /* Check for end-of-message. */
11934 putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
11935 /* Unconditionally dispatch. */
11936 putop(c, OP_DISPATCH, 0);
11937 }
11938
11939 /* For now we just loop back to the last field of the message (or if none,
11940 * the DISPATCH opcode for the message). */
11941 putop(c, OP_BRANCH, -LABEL_FIELD);
11942
11943 /* Insert both a label and a dispatch table entry for this end-of-msg. */
11944 label(c, LABEL_ENDMSG);
11945 val = upb_value_uint64(pcofs(c) - method->code_base.ofs);
11946 upb_inttable_insert(&method->dispatch, DISPATCH_ENDMSG, val);
11947
11948 putsel(c, OP_ENDMSG, UPB_ENDMSG_SELECTOR, h);
11949 putop(c, OP_RET);
11950
11951 upb_inttable_compact(&method->dispatch);
11952}
11953
11954/* Populate "methods" with new upb_pbdecodermethod objects reachable from "h".
11955 * Returns the method for these handlers.
11956 *
11957 * Generates a new method for every destination handlers reachable from "h". */
11958static void find_methods(compiler *c, const upb_handlers *h) {
11959 upb_value v;
11960 upb_msg_field_iter i;
11961 const upb_msgdef *md;
11962
11963 if (upb_inttable_lookupptr(&c->group->methods, h, &v))
11964 return;
11965 newmethod(h, c->group);
11966
11967 /* Find submethods. */
11968 md = upb_handlers_msgdef(h);
11969 for(upb_msg_field_begin(&i, md);
11970 !upb_msg_field_done(&i);
11971 upb_msg_field_next(&i)) {
11972 const upb_fielddef *f = upb_msg_iter_field(&i);
11973 const upb_handlers *sub_h;
11974 if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
11975 (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) {
11976 /* We only generate a decoder method for submessages with handlers.
11977 * Others will be parsed as unknown fields. */
11978 find_methods(c, sub_h);
11979 }
11980 }
11981}
11982
11983/* (Re-)compile bytecode for all messages in "msgs."
11984 * Overwrites any existing bytecode in "c". */
11985static void compile_methods(compiler *c) {
11986 upb_inttable_iter i;
11987
11988 /* Start over at the beginning of the bytecode. */
11989 c->pc = c->group->bytecode;
11990
11991 upb_inttable_begin(&i, &c->group->methods);
11992 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
11993 upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
11994 compile_method(c, method);
11995 }
11996}
11997
11998static void set_bytecode_handlers(mgroup *g) {
11999 upb_inttable_iter i;
12000 upb_inttable_begin(&i, &g->methods);
12001 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
12002 upb_pbdecodermethod *m = upb_value_getptr(upb_inttable_iter_value(&i));
12003 upb_byteshandler *h = &m->input_handler_;
12004
12005 m->code_base.ptr = g->bytecode + m->code_base.ofs;
12006
12007 upb_byteshandler_setstartstr(h, upb_pbdecoder_startbc, m->code_base.ptr);
12008 upb_byteshandler_setstring(h, upb_pbdecoder_decode, g);
12009 upb_byteshandler_setendstr(h, upb_pbdecoder_end, m);
12010 }
12011}
12012
12013
12014/* JIT setup. *****************************************************************/
12015
12016#ifdef UPB_USE_JIT_X64
12017
12018static void sethandlers(mgroup *g, bool allowjit) {
12019 g->jit_code = NULL;
12020 if (allowjit) {
12021 /* Compile byte-code into machine code, create handlers. */
12022 upb_pbdecoder_jit(g);
12023 } else {
12024 set_bytecode_handlers(g);
12025 }
12026}
12027
12028#else /* UPB_USE_JIT_X64 */
12029
12030static void sethandlers(mgroup *g, bool allowjit) {
12031 /* No JIT compiled in; use bytecode handlers unconditionally. */
12032 UPB_UNUSED(allowjit);
12033 set_bytecode_handlers(g);
12034}
12035
12036#endif /* UPB_USE_JIT_X64 */
12037
12038
12039/* TODO(haberman): allow this to be constructed for an arbitrary set of dest
12040 * handlers and other mgroups (but verify we have a transitive closure). */
12041const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
12042 const void *owner) {
12043 mgroup *g;
12044 compiler *c;
12045
12046 UPB_UNUSED(allowjit);
12047 UPB_ASSERT(upb_handlers_isfrozen(dest));
12048
12049 g = newgroup(owner);
12050 c = newcompiler(g, lazy);
12051 find_methods(c, dest);
12052
12053 /* We compile in two passes:
12054 * 1. all messages are assigned relative offsets from the beginning of the
12055 * bytecode (saved in method->code_base).
12056 * 2. forwards OP_CALL instructions can be correctly linked since message
12057 * offsets have been previously assigned.
12058 *
12059 * Could avoid the second pass by linking OP_CALL instructions somehow. */
12060 compile_methods(c);
12061 compile_methods(c);
12062 g->bytecode_end = c->pc;
12063 freecompiler(c);
12064
12065#ifdef UPB_DUMP_BYTECODE
12066 {
12067 FILE *f = fopen("/tmp/upb-bytecode", "w");
12068 UPB_ASSERT(f);
12069 dumpbc(g->bytecode, g->bytecode_end, stderr);
12070 dumpbc(g->bytecode, g->bytecode_end, f);
12071 fclose(f);
12072
12073 f = fopen("/tmp/upb-bytecode.bin", "wb");
12074 UPB_ASSERT(f);
12075 fwrite(g->bytecode, 1, g->bytecode_end - g->bytecode, f);
12076 fclose(f);
12077 }
12078#endif
12079
12080 sethandlers(g, allowjit);
12081 return g;
12082}
12083
12084
12085/* upb_pbcodecache ************************************************************/
12086
12087void upb_pbcodecache_init(upb_pbcodecache *c) {
12088 upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR);
12089 c->allow_jit_ = true;
12090}
12091
12092void upb_pbcodecache_uninit(upb_pbcodecache *c) {
12093 upb_inttable_iter i;
12094 upb_inttable_begin(&i, &c->groups);
12095 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
12096 const mgroup *group = upb_value_getconstptr(upb_inttable_iter_value(&i));
12097 mgroup_unref(group, c);
12098 }
12099 upb_inttable_uninit(&c->groups);
12100}
12101
12102bool upb_pbcodecache_allowjit(const upb_pbcodecache *c) {
12103 return c->allow_jit_;
12104}
12105
12106bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow) {
12107 if (upb_inttable_count(&c->groups) > 0)
12108 return false;
12109 c->allow_jit_ = allow;
12110 return true;
12111}
12112
12113const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
12114 upb_pbcodecache *c, const upb_pbdecodermethodopts *opts) {
12115 upb_value v;
12116 bool ok;
12117
12118 /* Right now we build a new DecoderMethod every time.
12119 * TODO(haberman): properly cache methods by their true key. */
12120 const mgroup *g = mgroup_new(opts->handlers, c->allow_jit_, opts->lazy, c);
12121 upb_inttable_push(&c->groups, upb_value_constptr(g));
12122
12123 ok = upb_inttable_lookupptr(&g->methods, opts->handlers, &v);
12124 UPB_ASSERT(ok);
12125 return upb_value_getptr(v);
12126}
12127
12128
12129/* upb_pbdecodermethodopts ****************************************************/
12130
12131void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
12132 const upb_handlers *h) {
12133 opts->handlers = h;
12134 opts->lazy = false;
12135}
12136
12137void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
12138 opts->lazy = lazy;
12139}
12140/*
12141** upb::Decoder (Bytecode Decoder VM)
12142**
12143** Bytecode must previously have been generated using the bytecode compiler in
12144** compile_decoder.c. This decoder then walks through the bytecode op-by-op to
12145** parse the input.
12146**
12147** Decoding is fully resumable; we just keep a pointer to the current bytecode
12148** instruction and resume from there. A fair amount of the logic here is to
12149** handle the fact that values can span buffer seams and we have to be able to
12150** be capable of suspending/resuming from any byte in the stream. This
12151** sometimes requires keeping a few trailing bytes from the last buffer around
12152** in the "residual" buffer.
12153*/
12154
12155#include <inttypes.h>
12156#include <stddef.h>
12157
12158#ifdef UPB_DUMP_BYTECODE
12159#include <stdio.h>
12160#endif
12161
12162#define CHECK_SUSPEND(x) if (!(x)) return upb_pbdecoder_suspend(d);
12163
12164/* Error messages that are shared between the bytecode and JIT decoders. */
12165const char *kPbDecoderStackOverflow = "Nesting too deep.";
12166const char *kPbDecoderSubmessageTooLong =
12167 "Submessage end extends past enclosing submessage.";
12168
12169/* Error messages shared within this file. */
12170static const char *kUnterminatedVarint = "Unterminated varint.";
12171
12172/* upb_pbdecoder **************************************************************/
12173
12174static opcode halt = OP_HALT;
12175
12176/* A dummy character we can point to when the user passes us a NULL buffer.
12177 * We need this because in C (NULL + 0) and (NULL - NULL) are undefined
12178 * behavior, which would invalidate functions like curbufleft(). */
12179static const char dummy_char;
12180
12181/* Whether an op consumes any of the input buffer. */
12182static bool consumes_input(opcode op) {
12183 switch (op) {
12184 case OP_SETDISPATCH:
12185 case OP_STARTMSG:
12186 case OP_ENDMSG:
12187 case OP_STARTSEQ:
12188 case OP_ENDSEQ:
12189 case OP_STARTSUBMSG:
12190 case OP_ENDSUBMSG:
12191 case OP_STARTSTR:
12192 case OP_ENDSTR:
12193 case OP_PUSHTAGDELIM:
12194 case OP_POP:
12195 case OP_SETDELIM:
12196 case OP_SETBIGGROUPNUM:
12197 case OP_CHECKDELIM:
12198 case OP_CALL:
12199 case OP_RET:
12200 case OP_BRANCH:
12201 return false;
12202 default:
12203 return true;
12204 }
12205}
12206
12207static size_t stacksize(upb_pbdecoder *d, size_t entries) {
12208 UPB_UNUSED(d);
12209 return entries * sizeof(upb_pbdecoder_frame);
12210}
12211
12212static size_t callstacksize(upb_pbdecoder *d, size_t entries) {
12213 UPB_UNUSED(d);
12214
12215#ifdef UPB_USE_JIT_X64
12216 if (d->method_->is_native_) {
12217 /* Each native stack frame needs two pointers, plus we need a few frames for
12218 * the enter/exit trampolines. */
12219 size_t ret = entries * sizeof(void*) * 2;
12220 ret += sizeof(void*) * 10;
12221 return ret;
12222 }
12223#endif
12224
12225 return entries * sizeof(uint32_t*);
12226}
12227
12228
12229static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
12230
12231/* It's unfortunate that we have to micro-manage the compiler with
12232 * UPB_FORCEINLINE and UPB_NOINLINE, especially since this tuning is necessarily
12233 * specific to one hardware configuration. But empirically on a Core i7,
12234 * performance increases 30-50% with these annotations. Every instance where
12235 * these appear, gcc 4.2.1 made the wrong decision and degraded performance in
12236 * benchmarks. */
12237
12238static void seterr(upb_pbdecoder *d, const char *msg) {
12239 upb_status status = UPB_STATUS_INIT;
12240 upb_status_seterrmsg(&status, msg);
12241 upb_env_reporterror(d->env, &status);
12242}
12243
12244void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
12245 seterr(d, msg);
12246}
12247
12248
12249/* Buffering ******************************************************************/
12250
12251/* We operate on one buffer at a time, which is either the user's buffer passed
12252 * to our "decode" callback or some residual bytes from the previous buffer. */
12253
12254/* How many bytes can be safely read from d->ptr without reading past end-of-buf
12255 * or past the current delimited end. */
12256static size_t curbufleft(const upb_pbdecoder *d) {
12257 UPB_ASSERT(d->data_end >= d->ptr);
12258 return d->data_end - d->ptr;
12259}
12260
12261/* How many bytes are available before end-of-buffer. */
12262static size_t bufleft(const upb_pbdecoder *d) {
12263 return d->end - d->ptr;
12264}
12265
12266/* Overall stream offset of d->ptr. */
12267uint64_t offset(const upb_pbdecoder *d) {
12268 return d->bufstart_ofs + (d->ptr - d->buf);
12269}
12270
12271/* How many bytes are available before the end of this delimited region. */
12272size_t delim_remaining(const upb_pbdecoder *d) {
12273 return d->top->end_ofs - offset(d);
12274}
12275
12276/* Advances d->ptr. */
12277static void advance(upb_pbdecoder *d, size_t len) {
12278 UPB_ASSERT(curbufleft(d) >= len);
12279 d->ptr += len;
12280}
12281
12282static bool in_buf(const char *p, const char *buf, const char *end) {
12283 return p >= buf && p <= end;
12284}
12285
12286static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
12287 return in_buf(p, d->residual, d->residual_end);
12288}
12289
12290/* Calculates the delim_end value, which is affected by both the current buffer
12291 * and the parsing stack, so must be called whenever either is updated. */
12292static void set_delim_end(upb_pbdecoder *d) {
12293 size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
12294 if (delim_ofs <= (size_t)(d->end - d->buf)) {
12295 d->delim_end = d->buf + delim_ofs;
12296 d->data_end = d->delim_end;
12297 } else {
12298 d->data_end = d->end;
12299 d->delim_end = NULL;
12300 }
12301}
12302
12303static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end) {
12304 d->ptr = buf;
12305 d->buf = buf;
12306 d->end = end;
12307 set_delim_end(d);
12308}
12309
12310static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) {
12311 UPB_ASSERT(curbufleft(d) == 0);
12312 d->bufstart_ofs += (d->end - d->buf);
12313 switchtobuf(d, buf, buf + len);
12314}
12315
12316static void checkpoint(upb_pbdecoder *d) {
12317 /* The assertion here is in the interests of efficiency, not correctness.
12318 * We are trying to ensure that we don't checkpoint() more often than
12319 * necessary. */
12320 UPB_ASSERT(d->checkpoint != d->ptr);
12321 d->checkpoint = d->ptr;
12322}
12323
12324/* Skips "bytes" bytes in the stream, which may be more than available. If we
12325 * skip more bytes than are available, we return a long read count to the caller
12326 * indicating how many bytes can be skipped over before passing actual data
12327 * again. Skipped bytes can pass a NULL buffer and the decoder guarantees they
12328 * won't actually be read.
12329 */
12330static int32_t skip(upb_pbdecoder *d, size_t bytes) {
12331 UPB_ASSERT(!in_residual_buf(d, d->ptr) || d->size_param == 0);
12332 UPB_ASSERT(d->skip == 0);
12333 if (bytes > delim_remaining(d)) {
12334 seterr(d, "Skipped value extended beyond enclosing submessage.");
12335 return upb_pbdecoder_suspend(d);
12336 } else if (bufleft(d) >= bytes) {
12337 /* Skipped data is all in current buffer, and more is still available. */
12338 advance(d, bytes);
12339 d->skip = 0;
12340 return DECODE_OK;
12341 } else {
12342 /* Skipped data extends beyond currently available buffers. */
12343 d->pc = d->last;
12344 d->skip = bytes - curbufleft(d);
12345 d->bufstart_ofs += (d->end - d->buf);
12346 d->residual_end = d->residual;
12347 switchtobuf(d, d->residual, d->residual_end);
12348 return d->size_param + d->skip;
12349 }
12350}
12351
12352
12353/* Resumes the decoder from an initial state or from a previous suspend. */
12354int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
12355 size_t size, const upb_bufhandle *handle) {
12356 UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */
12357
12358 /* d->skip and d->residual_end could probably elegantly be represented
12359 * as a single variable, to more easily represent this invariant. */
12360 UPB_ASSERT(!(d->skip && d->residual_end > d->residual));
12361
12362 /* We need to remember the original size_param, so that the value we return
12363 * is relative to it, even if we do some skipping first. */
12364 d->size_param = size;
12365 d->handle = handle;
12366
12367 /* Have to handle this case specially (ie. not with skip()) because the user
12368 * is allowed to pass a NULL buffer here, which won't allow us to safely
12369 * calculate a d->end or use our normal functions like curbufleft(). */
12370 if (d->skip && d->skip >= size) {
12371 d->skip -= size;
12372 d->bufstart_ofs += size;
12373 buf = &dummy_char;
12374 size = 0;
12375
12376 /* We can't just return now, because we might need to execute some ops
12377 * like CHECKDELIM, which could call some callbacks and pop the stack. */
12378 }
12379
12380 /* We need to pretend that this was the actual buffer param, since some of the
12381 * calculations assume that d->ptr/d->buf is relative to this. */
12382 d->buf_param = buf;
12383
12384 if (!buf) {
12385 /* NULL buf is ok if its entire span is covered by the "skip" above, but
12386 * by this point we know that "skip" doesn't cover the buffer. */
12387 seterr(d, "Passed NULL buffer over non-skippable region.");
12388 return upb_pbdecoder_suspend(d);
12389 }
12390
12391 if (d->residual_end > d->residual) {
12392 /* We have residual bytes from the last buffer. */
12393 UPB_ASSERT(d->ptr == d->residual);
12394 } else {
12395 switchtobuf(d, buf, buf + size);
12396 }
12397
12398 d->checkpoint = d->ptr;
12399
12400 /* Handle skips that don't cover the whole buffer (as above). */
12401 if (d->skip) {
12402 size_t skip_bytes = d->skip;
12403 d->skip = 0;
12404 CHECK_RETURN(skip(d, skip_bytes));
12405 checkpoint(d);
12406 }
12407
12408 /* If we're inside an unknown group, continue to parse unknown values. */
12409 if (d->top->groupnum < 0) {
12410 CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0));
12411 checkpoint(d);
12412 }
12413
12414 return DECODE_OK;
12415}
12416
12417/* Suspends the decoder at the last checkpoint, without saving any residual
12418 * bytes. If there are any unconsumed bytes, returns a short byte count. */
12419size_t upb_pbdecoder_suspend(upb_pbdecoder *d) {
12420 d->pc = d->last;
12421 if (d->checkpoint == d->residual) {
12422 /* Checkpoint was in residual buf; no user bytes were consumed. */
12423 d->ptr = d->residual;
12424 return 0;
12425 } else {
12426 size_t ret = d->size_param - (d->end - d->checkpoint);
12427 UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
12428 UPB_ASSERT(d->buf == d->buf_param || d->buf == &dummy_char);
12429
12430 d->bufstart_ofs += (d->checkpoint - d->buf);
12431 d->residual_end = d->residual;
12432 switchtobuf(d, d->residual, d->residual_end);
12433 return ret;
12434 }
12435}
12436
12437/* Suspends the decoder at the last checkpoint, and saves any unconsumed
12438 * bytes in our residual buffer. This is necessary if we need more user
12439 * bytes to form a complete value, which might not be contiguous in the
12440 * user's buffers. Always consumes all user bytes. */
12441static size_t suspend_save(upb_pbdecoder *d) {
12442 /* We hit end-of-buffer before we could parse a full value.
12443 * Save any unconsumed bytes (if any) to the residual buffer. */
12444 d->pc = d->last;
12445
12446 if (d->checkpoint == d->residual) {
12447 /* Checkpoint was in residual buf; append user byte(s) to residual buf. */
12448 UPB_ASSERT((d->residual_end - d->residual) + d->size_param <=
12449 sizeof(d->residual));
12450 if (!in_residual_buf(d, d->ptr)) {
12451 d->bufstart_ofs -= (d->residual_end - d->residual);
12452 }
12453 memcpy(d->residual_end, d->buf_param, d->size_param);
12454 d->residual_end += d->size_param;
12455 } else {
12456 /* Checkpoint was in user buf; old residual bytes not needed. */
12457 size_t save;
12458 UPB_ASSERT(!in_residual_buf(d, d->checkpoint));
12459
12460 d->ptr = d->checkpoint;
12461 save = curbufleft(d);
12462 UPB_ASSERT(save <= sizeof(d->residual));
12463 memcpy(d->residual, d->ptr, save);
12464 d->residual_end = d->residual + save;
12465 d->bufstart_ofs = offset(d);
12466 }
12467
12468 switchtobuf(d, d->residual, d->residual_end);
12469 return d->size_param;
12470}
12471
12472/* Copies the next "bytes" bytes into "buf" and advances the stream.
12473 * Requires that this many bytes are available in the current buffer. */
12474UPB_FORCEINLINE static void consumebytes(upb_pbdecoder *d, void *buf,
12475 size_t bytes) {
12476 UPB_ASSERT(bytes <= curbufleft(d));
12477 memcpy(buf, d->ptr, bytes);
12478 advance(d, bytes);
12479}
12480
12481/* Slow path for getting the next "bytes" bytes, regardless of whether they are
12482 * available in the current buffer or not. Returns a status code as described
12483 * in decoder.int.h. */
12484UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
12485 size_t bytes) {
12486 const size_t avail = curbufleft(d);
12487 consumebytes(d, buf, avail);
12488 bytes -= avail;
12489 UPB_ASSERT(bytes > 0);
12490 if (in_residual_buf(d, d->ptr)) {
12491 advancetobuf(d, d->buf_param, d->size_param);
12492 }
12493 if (curbufleft(d) >= bytes) {
12494 consumebytes(d, (char *)buf + avail, bytes);
12495 return DECODE_OK;
12496 } else if (d->data_end == d->delim_end) {
12497 seterr(d, "Submessage ended in the middle of a value or group");
12498 return upb_pbdecoder_suspend(d);
12499 } else {
12500 return suspend_save(d);
12501 }
12502}
12503
12504/* Gets the next "bytes" bytes, regardless of whether they are available in the
12505 * current buffer or not. Returns a status code as described in decoder.int.h.
12506 */
12507UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf,
12508 size_t bytes) {
12509 if (curbufleft(d) >= bytes) {
12510 /* Buffer has enough data to satisfy. */
12511 consumebytes(d, buf, bytes);
12512 return DECODE_OK;
12513 } else {
12514 return getbytes_slow(d, buf, bytes);
12515 }
12516}
12517
12518UPB_NOINLINE static size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
12519 size_t bytes) {
12520 size_t ret = curbufleft(d);
12521 memcpy(buf, d->ptr, ret);
12522 if (in_residual_buf(d, d->ptr)) {
12523 size_t copy = UPB_MIN(bytes - ret, d->size_param);
12524 memcpy((char *)buf + ret, d->buf_param, copy);
12525 ret += copy;
12526 }
12527 return ret;
12528}
12529
12530UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf,
12531 size_t bytes) {
12532 if (curbufleft(d) >= bytes) {
12533 memcpy(buf, d->ptr, bytes);
12534 return bytes;
12535 } else {
12536 return peekbytes_slow(d, buf, bytes);
12537 }
12538}
12539
12540
12541/* Decoding of wire types *****************************************************/
12542
12543/* Slow path for decoding a varint from the current buffer position.
12544 * Returns a status code as described in decoder.int.h. */
12545UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
12546 uint64_t *u64) {
12547 uint8_t byte = 0x80;
12548 int bitpos;
12549 *u64 = 0;
12550 for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
12551 CHECK_RETURN(getbytes(d, &byte, 1));
12552 *u64 |= (uint64_t)(byte & 0x7F) << bitpos;
12553 }
12554 if(bitpos == 70 && (byte & 0x80)) {
12555 seterr(d, kUnterminatedVarint);
12556 return upb_pbdecoder_suspend(d);
12557 }
12558 return DECODE_OK;
12559}
12560
12561/* Decodes a varint from the current buffer position.
12562 * Returns a status code as described in decoder.int.h. */
12563UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
12564 if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
12565 *u64 = *d->ptr;
12566 advance(d, 1);
12567 return DECODE_OK;
12568 } else if (curbufleft(d) >= 10) {
12569 /* Fast case. */
12570 upb_decoderet r = upb_vdecode_fast(d->ptr);
12571 if (r.p == NULL) {
12572 seterr(d, kUnterminatedVarint);
12573 return upb_pbdecoder_suspend(d);
12574 }
12575 advance(d, r.p - d->ptr);
12576 *u64 = r.val;
12577 return DECODE_OK;
12578 } else {
12579 /* Slow case -- varint spans buffer seam. */
12580 return upb_pbdecoder_decode_varint_slow(d, u64);
12581 }
12582}
12583
12584/* Decodes a 32-bit varint from the current buffer position.
12585 * Returns a status code as described in decoder.int.h. */
12586UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
12587 uint64_t u64;
12588 int32_t ret = decode_varint(d, &u64);
12589 if (ret >= 0) return ret;
12590 if (u64 > UINT32_MAX) {
12591 seterr(d, "Unterminated 32-bit varint");
12592 /* TODO(haberman) guarantee that this function return is >= 0 somehow,
12593 * so we know this path will always be treated as error by our caller.
12594 * Right now the size_t -> int32_t can overflow and produce negative values.
12595 */
12596 *u32 = 0;
12597 return upb_pbdecoder_suspend(d);
12598 }
12599 *u32 = u64;
12600 return DECODE_OK;
12601}
12602
12603/* Decodes a fixed32 from the current buffer position.
12604 * Returns a status code as described in decoder.int.h.
12605 * TODO: proper byte swapping for big-endian machines. */
12606UPB_FORCEINLINE static int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
12607 return getbytes(d, u32, 4);
12608}
12609
12610/* Decodes a fixed64 from the current buffer position.
12611 * Returns a status code as described in decoder.int.h.
12612 * TODO: proper byte swapping for big-endian machines. */
12613UPB_FORCEINLINE static int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
12614 return getbytes(d, u64, 8);
12615}
12616
12617/* Non-static versions of the above functions.
12618 * These are called by the JIT for fallback paths. */
12619int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) {
12620 return decode_fixed32(d, u32);
12621}
12622
12623int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) {
12624 return decode_fixed64(d, u64);
12625}
12626
12627static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; }
12628static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; }
12629
12630/* Pushes a frame onto the decoder stack. */
12631static bool decoder_push(upb_pbdecoder *d, uint64_t end) {
12632 upb_pbdecoder_frame *fr = d->top;
12633
12634 if (end > fr->end_ofs) {
12635 seterr(d, kPbDecoderSubmessageTooLong);
12636 return false;
12637 } else if (fr == d->limit) {
12638 seterr(d, kPbDecoderStackOverflow);
12639 return false;
12640 }
12641
12642 fr++;
12643 fr->end_ofs = end;
12644 fr->dispatch = NULL;
12645 fr->groupnum = 0;
12646 d->top = fr;
12647 return true;
12648}
12649
12650static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
12651 /* While we expect to see an "end" tag (either ENDGROUP or a non-sequence
12652 * field number) prior to hitting any enclosing submessage end, pushing our
12653 * existing delim end prevents us from continuing to parse values from a
12654 * corrupt proto that doesn't give us an END tag in time. */
12655 if (!decoder_push(d, d->top->end_ofs))
12656 return false;
12657 d->top->groupnum = arg;
12658 return true;
12659}
12660
12661/* Pops a frame from the decoder stack. */
12662static void decoder_pop(upb_pbdecoder *d) { d->top--; }
12663
12664UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
12665 uint64_t expected) {
12666 uint64_t data = 0;
12667 size_t bytes = upb_value_size(expected);
12668 size_t read = peekbytes(d, &data, bytes);
12669 if (read == bytes && data == expected) {
12670 /* Advance past matched bytes. */
12671 int32_t ok = getbytes(d, &data, read);
12672 UPB_ASSERT(ok < 0);
12673 return DECODE_OK;
12674 } else if (read < bytes && memcmp(&data, &expected, read) == 0) {
12675 return suspend_save(d);
12676 } else {
12677 return DECODE_MISMATCH;
12678 }
12679}
12680
12681int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
12682 uint8_t wire_type) {
12683 if (fieldnum >= 0)
12684 goto have_tag;
12685
12686 while (true) {
12687 uint32_t tag;
12688 CHECK_RETURN(decode_v32(d, &tag));
12689 wire_type = tag & 0x7;
12690 fieldnum = tag >> 3;
12691
12692have_tag:
12693 if (fieldnum == 0) {
12694 seterr(d, "Saw invalid field number (0)");
12695 return upb_pbdecoder_suspend(d);
12696 }
12697
12698 switch (wire_type) {
12699 case UPB_WIRE_TYPE_32BIT:
12700 CHECK_RETURN(skip(d, 4));
12701 break;
12702 case UPB_WIRE_TYPE_64BIT:
12703 CHECK_RETURN(skip(d, 8));
12704 break;
12705 case UPB_WIRE_TYPE_VARINT: {
12706 uint64_t u64;
12707 CHECK_RETURN(decode_varint(d, &u64));
12708 break;
12709 }
12710 case UPB_WIRE_TYPE_DELIMITED: {
12711 uint32_t len;
12712 CHECK_RETURN(decode_v32(d, &len));
12713 CHECK_RETURN(skip(d, len));
12714 break;
12715 }
12716 case UPB_WIRE_TYPE_START_GROUP:
12717 CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
12718 break;
12719 case UPB_WIRE_TYPE_END_GROUP:
12720 if (fieldnum == -d->top->groupnum) {
12721 decoder_pop(d);
12722 } else if (fieldnum == d->top->groupnum) {
12723 return DECODE_ENDGROUP;
12724 } else {
12725 seterr(d, "Unmatched ENDGROUP tag.");
12726 return upb_pbdecoder_suspend(d);
12727 }
12728 break;
12729 default:
12730 seterr(d, "Invalid wire type");
12731 return upb_pbdecoder_suspend(d);
12732 }
12733
12734 if (d->top->groupnum >= 0) {
12735 /* TODO: More code needed for handling unknown groups. */
12736 upb_sink_putunknown(&d->top->sink, d->checkpoint, d->ptr - d->checkpoint);
12737 return DECODE_OK;
12738 }
12739
12740 /* Unknown group -- continue looping over unknown fields. */
12741 checkpoint(d);
12742 }
12743}
12744
12745static void goto_endmsg(upb_pbdecoder *d) {
12746 upb_value v;
12747 bool found = upb_inttable_lookup32(d->top->dispatch, DISPATCH_ENDMSG, &v);
12748 UPB_ASSERT(found);
12749 d->pc = d->top->base + upb_value_getuint64(v);
12750}
12751
12752/* Parses a tag and jumps to the corresponding bytecode instruction for this
12753 * field.
12754 *
12755 * If the tag is unknown (or the wire type doesn't match), parses the field as
12756 * unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode
12757 * instruction for the end of message. */
12758static int32_t dispatch(upb_pbdecoder *d) {
12759 upb_inttable *dispatch = d->top->dispatch;
12760 uint32_t tag;
12761 uint8_t wire_type;
12762 uint32_t fieldnum;
12763 upb_value val;
12764 int32_t retval;
12765
12766 /* Decode tag. */
12767 CHECK_RETURN(decode_v32(d, &tag));
12768 wire_type = tag & 0x7;
12769 fieldnum = tag >> 3;
12770
12771 /* Lookup tag. Because of packed/non-packed compatibility, we have to
12772 * check the wire type against two possibilities. */
12773 if (fieldnum != DISPATCH_ENDMSG &&
12774 upb_inttable_lookup32(dispatch, fieldnum, &val)) {
12775 uint64_t v = upb_value_getuint64(val);
12776 if (wire_type == (v & 0xff)) {
12777 d->pc = d->top->base + (v >> 16);
12778 return DECODE_OK;
12779 } else if (wire_type == ((v >> 8) & 0xff)) {
12780 bool found =
12781 upb_inttable_lookup(dispatch, fieldnum + UPB_MAX_FIELDNUMBER, &val);
12782 UPB_ASSERT(found);
12783 d->pc = d->top->base + upb_value_getuint64(val);
12784 return DECODE_OK;
12785 }
12786 }
12787
12788 /* We have some unknown fields (or ENDGROUP) to parse. The DISPATCH or TAG
12789 * bytecode that triggered this is preceded by a CHECKDELIM bytecode which
12790 * we need to back up to, so that when we're done skipping unknown data we
12791 * can re-check the delimited end. */
12792 d->last--; /* Necessary if we get suspended */
12793 d->pc = d->last;
12794 UPB_ASSERT(getop(*d->last) == OP_CHECKDELIM);
12795
12796 /* Unknown field or ENDGROUP. */
12797 retval = upb_pbdecoder_skipunknown(d, fieldnum, wire_type);
12798
12799 CHECK_RETURN(retval);
12800
12801 if (retval == DECODE_ENDGROUP) {
12802 goto_endmsg(d);
12803 return DECODE_OK;
12804 }
12805
12806 return DECODE_OK;
12807}
12808
12809/* Callers know that the stack is more than one deep because the opcodes that
12810 * call this only occur after PUSH operations. */
12811upb_pbdecoder_frame *outer_frame(upb_pbdecoder *d) {
12812 UPB_ASSERT(d->top != d->stack);
12813 return d->top - 1;
12814}
12815
12816
12817/* The main decoding loop *****************************************************/
12818
12819/* The main decoder VM function. Uses traditional bytecode dispatch loop with a
12820 * switch() statement. */
12821size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group,
12822 const upb_bufhandle* handle) {
12823
12824#define VMCASE(op, code) \
12825 case op: { code; if (consumes_input(op)) checkpoint(d); break; }
12826#define PRIMITIVE_OP(type, wt, name, convfunc, ctype) \
12827 VMCASE(OP_PARSE_ ## type, { \
12828 ctype val; \
12829 CHECK_RETURN(decode_ ## wt(d, &val)); \
12830 upb_sink_put ## name(&d->top->sink, arg, (convfunc)(val)); \
12831 })
12832
12833 while(1) {
12834 int32_t instruction;
12835 opcode op;
12836 uint32_t arg;
12837 int32_t longofs;
12838
12839 d->last = d->pc;
12840 instruction = *d->pc++;
12841 op = getop(instruction);
12842 arg = instruction >> 8;
12843 longofs = arg;
12844 UPB_ASSERT(d->ptr != d->residual_end);
12845 UPB_UNUSED(group);
12846#ifdef UPB_DUMP_BYTECODE
12847 fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d "
12848 "%x %s (%d)\n",
12849 (int)offset(d),
12850 (int)(d->ptr - d->buf),
12851 (int)(d->data_end - d->ptr),
12852 (int)(d->end - d->ptr),
12853 (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)),
12854 (int)(d->pc - 1 - group->bytecode),
12855 upb_pbdecoder_getopname(op),
12856 arg);
12857#endif
12858 switch (op) {
12859 /* Technically, we are losing data if we see a 32-bit varint that is not
12860 * properly sign-extended. We could detect this and error about the data
12861 * loss, but proto2 does not do this, so we pass. */
12862 PRIMITIVE_OP(INT32, varint, int32, int32_t, uint64_t)
12863 PRIMITIVE_OP(INT64, varint, int64, int64_t, uint64_t)
12864 PRIMITIVE_OP(UINT32, varint, uint32, uint32_t, uint64_t)
12865 PRIMITIVE_OP(UINT64, varint, uint64, uint64_t, uint64_t)
12866 PRIMITIVE_OP(FIXED32, fixed32, uint32, uint32_t, uint32_t)
12867 PRIMITIVE_OP(FIXED64, fixed64, uint64, uint64_t, uint64_t)
12868 PRIMITIVE_OP(SFIXED32, fixed32, int32, int32_t, uint32_t)
12869 PRIMITIVE_OP(SFIXED64, fixed64, int64, int64_t, uint64_t)
12870 PRIMITIVE_OP(BOOL, varint, bool, bool, uint64_t)
12871 PRIMITIVE_OP(DOUBLE, fixed64, double, as_double, uint64_t)
12872 PRIMITIVE_OP(FLOAT, fixed32, float, as_float, uint32_t)
12873 PRIMITIVE_OP(SINT32, varint, int32, upb_zzdec_32, uint64_t)
12874 PRIMITIVE_OP(SINT64, varint, int64, upb_zzdec_64, uint64_t)
12875
12876 VMCASE(OP_SETDISPATCH,
12877 d->top->base = d->pc - 1;
12878 memcpy(&d->top->dispatch, d->pc, sizeof(void*));
12879 d->pc += sizeof(void*) / sizeof(uint32_t);
12880 )
12881 VMCASE(OP_STARTMSG,
12882 CHECK_SUSPEND(upb_sink_startmsg(&d->top->sink));
12883 )
12884 VMCASE(OP_ENDMSG,
12885 CHECK_SUSPEND(upb_sink_endmsg(&d->top->sink, d->status));
12886 )
12887 VMCASE(OP_STARTSEQ,
12888 upb_pbdecoder_frame *outer = outer_frame(d);
12889 CHECK_SUSPEND(upb_sink_startseq(&outer->sink, arg, &d->top->sink));
12890 )
12891 VMCASE(OP_ENDSEQ,
12892 CHECK_SUSPEND(upb_sink_endseq(&d->top->sink, arg));
12893 )
12894 VMCASE(OP_STARTSUBMSG,
12895 upb_pbdecoder_frame *outer = outer_frame(d);
12896 CHECK_SUSPEND(upb_sink_startsubmsg(&outer->sink, arg, &d->top->sink));
12897 )
12898 VMCASE(OP_ENDSUBMSG,
12899 CHECK_SUSPEND(upb_sink_endsubmsg(&d->top->sink, arg));
12900 )
12901 VMCASE(OP_STARTSTR,
12902 uint32_t len = delim_remaining(d);
12903 upb_pbdecoder_frame *outer = outer_frame(d);
12904 CHECK_SUSPEND(upb_sink_startstr(&outer->sink, arg, len, &d->top->sink));
12905 if (len == 0) {
12906 d->pc++; /* Skip OP_STRING. */
12907 }
12908 )
12909 VMCASE(OP_STRING,
12910 uint32_t len = curbufleft(d);
12911 size_t n = upb_sink_putstring(&d->top->sink, arg, d->ptr, len, handle);
12912 if (n > len) {
12913 if (n > delim_remaining(d)) {
12914 seterr(d, "Tried to skip past end of string.");
12915 return upb_pbdecoder_suspend(d);
12916 } else {
12917 int32_t ret = skip(d, n);
12918 /* This shouldn't return DECODE_OK, because n > len. */
12919 UPB_ASSERT(ret >= 0);
12920 return ret;
12921 }
12922 }
12923 advance(d, n);
12924 if (n < len || d->delim_end == NULL) {
12925 /* We aren't finished with this string yet. */
12926 d->pc--; /* Repeat OP_STRING. */
12927 if (n > 0) checkpoint(d);
12928 return upb_pbdecoder_suspend(d);
12929 }
12930 )
12931 VMCASE(OP_ENDSTR,
12932 CHECK_SUSPEND(upb_sink_endstr(&d->top->sink, arg));
12933 )
12934 VMCASE(OP_PUSHTAGDELIM,
12935 CHECK_SUSPEND(pushtagdelim(d, arg));
12936 )
12937 VMCASE(OP_SETBIGGROUPNUM,
12938 d->top->groupnum = *d->pc++;
12939 )
12940 VMCASE(OP_POP,
12941 UPB_ASSERT(d->top > d->stack);
12942 decoder_pop(d);
12943 )
12944 VMCASE(OP_PUSHLENDELIM,
12945 uint32_t len;
12946 CHECK_RETURN(decode_v32(d, &len));
12947 CHECK_SUSPEND(decoder_push(d, offset(d) + len));
12948 set_delim_end(d);
12949 )
12950 VMCASE(OP_SETDELIM,
12951 set_delim_end(d);
12952 )
12953 VMCASE(OP_CHECKDELIM,
12954 /* We are guaranteed of this assert because we never allow ourselves to
12955 * consume bytes beyond data_end, which covers delim_end when non-NULL.
12956 */
12957 UPB_ASSERT(!(d->delim_end && d->ptr > d->delim_end));
12958 if (d->ptr == d->delim_end)
12959 d->pc += longofs;
12960 )
12961 VMCASE(OP_CALL,
12962 d->callstack[d->call_len++] = d->pc;
12963 d->pc += longofs;
12964 )
12965 VMCASE(OP_RET,
12966 UPB_ASSERT(d->call_len > 0);
12967 d->pc = d->callstack[--d->call_len];
12968 )
12969 VMCASE(OP_BRANCH,
12970 d->pc += longofs;
12971 )
12972 VMCASE(OP_TAG1,
12973 uint8_t expected;
12974 CHECK_SUSPEND(curbufleft(d) > 0);
12975 expected = (arg >> 8) & 0xff;
12976 if (*d->ptr == expected) {
12977 advance(d, 1);
12978 } else {
12979 int8_t shortofs;
12980 badtag:
12981 shortofs = arg;
12982 if (shortofs == LABEL_DISPATCH) {
12983 CHECK_RETURN(dispatch(d));
12984 } else {
12985 d->pc += shortofs;
12986 break; /* Avoid checkpoint(). */
12987 }
12988 }
12989 )
12990 VMCASE(OP_TAG2,
12991 uint16_t expected;
12992 CHECK_SUSPEND(curbufleft(d) > 0);
12993 expected = (arg >> 8) & 0xffff;
12994 if (curbufleft(d) >= 2) {
12995 uint16_t actual;
12996 memcpy(&actual, d->ptr, 2);
12997 if (expected == actual) {
12998 advance(d, 2);
12999 } else {
13000 goto badtag;
13001 }
13002 } else {
13003 int32_t result = upb_pbdecoder_checktag_slow(d, expected);
13004 if (result == DECODE_MISMATCH) goto badtag;
13005 if (result >= 0) return result;
13006 }
13007 )
13008 VMCASE(OP_TAGN, {
13009 uint64_t expected;
13010 int32_t result;
13011 memcpy(&expected, d->pc, 8);
13012 d->pc += 2;
13013 result = upb_pbdecoder_checktag_slow(d, expected);
13014 if (result == DECODE_MISMATCH) goto badtag;
13015 if (result >= 0) return result;
13016 })
13017 VMCASE(OP_DISPATCH, {
13018 CHECK_RETURN(dispatch(d));
13019 })
13020 VMCASE(OP_HALT, {
13021 return d->size_param;
13022 })
13023 }
13024 }
13025}
13026
13027
13028/* BytesHandler handlers ******************************************************/
13029
13030void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) {
13031 upb_pbdecoder *d = closure;
13032 UPB_UNUSED(size_hint);
13033 d->top->end_ofs = UINT64_MAX;
13034 d->bufstart_ofs = 0;
13035 d->call_len = 1;
13036 d->callstack[0] = &halt;
13037 d->pc = pc;
13038 d->skip = 0;
13039 return d;
13040}
13041
13042void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint) {
13043 upb_pbdecoder *d = closure;
13044 UPB_UNUSED(hd);
13045 UPB_UNUSED(size_hint);
13046 d->top->end_ofs = UINT64_MAX;
13047 d->bufstart_ofs = 0;
13048 d->call_len = 0;
13049 d->skip = 0;
13050 return d;
13051}
13052
13053bool upb_pbdecoder_end(void *closure, const void *handler_data) {
13054 upb_pbdecoder *d = closure;
13055 const upb_pbdecodermethod *method = handler_data;
13056 uint64_t end;
13057 char dummy;
13058
13059 if (d->residual_end > d->residual) {
13060 seterr(d, "Unexpected EOF: decoder still has buffered unparsed data");
13061 return false;
13062 }
13063
13064 if (d->skip) {
13065 seterr(d, "Unexpected EOF inside skipped data");
13066 return false;
13067 }
13068
13069 if (d->top->end_ofs != UINT64_MAX) {
13070 seterr(d, "Unexpected EOF inside delimited string");
13071 return false;
13072 }
13073
13074 /* The user's end() call indicates that the message ends here. */
13075 end = offset(d);
13076 d->top->end_ofs = end;
13077
13078#ifdef UPB_USE_JIT_X64
13079 if (method->is_native_) {
13080 const mgroup *group = (const mgroup*)method->group;
13081 if (d->top != d->stack)
13082 d->stack->end_ofs = 0;
13083 group->jit_code(closure, method->code_base.ptr, &dummy, 0, NULL);
13084 } else
13085#endif
13086 {
13087 const uint32_t *p = d->pc;
13088 d->stack->end_ofs = end;
13089 /* Check the previous bytecode, but guard against beginning. */
13090 if (p != method->code_base.ptr) p--;
13091 if (getop(*p) == OP_CHECKDELIM) {
13092 /* Rewind from OP_TAG* to OP_CHECKDELIM. */
13093 UPB_ASSERT(getop(*d->pc) == OP_TAG1 ||
13094 getop(*d->pc) == OP_TAG2 ||
13095 getop(*d->pc) == OP_TAGN ||
13096 getop(*d->pc) == OP_DISPATCH);
13097 d->pc = p;
13098 }
13099 upb_pbdecoder_decode(closure, handler_data, &dummy, 0, NULL);
13100 }
13101
13102 if (d->call_len != 0) {
13103 seterr(d, "Unexpected EOF inside submessage or group");
13104 return false;
13105 }
13106
13107 return true;
13108}
13109
13110size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf,
13111 size_t size, const upb_bufhandle *handle) {
13112 int32_t result = upb_pbdecoder_resume(decoder, NULL, buf, size, handle);
13113
13114 if (result == DECODE_ENDGROUP) goto_endmsg(decoder);
13115 CHECK_RETURN(result);
13116
13117 return run_decoder_vm(decoder, group, handle);
13118}
13119
13120
13121/* Public API *****************************************************************/
13122
13123void upb_pbdecoder_reset(upb_pbdecoder *d) {
13124 d->top = d->stack;
13125 d->top->groupnum = 0;
13126 d->ptr = d->residual;
13127 d->buf = d->residual;
13128 d->end = d->residual;
13129 d->residual_end = d->residual;
13130}
13131
13132upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m,
13133 upb_sink *sink) {
13134 const size_t default_max_nesting = 64;
13135#ifndef NDEBUG
13136 size_t size_before = upb_env_bytesallocated(e);
13137#endif
13138
13139 upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder));
13140 if (!d) return NULL;
13141
13142 d->method_ = m;
13143 d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting));
13144 d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting));
13145 if (!d->stack || !d->callstack) {
13146 return NULL;
13147 }
13148
13149 d->env = e;
13150 d->limit = d->stack + default_max_nesting - 1;
13151 d->stack_size = default_max_nesting;
13152 d->status = NULL;
13153
13154 upb_pbdecoder_reset(d);
13155 upb_bytessink_reset(&d->input_, &m->input_handler_, d);
13156
13157 UPB_ASSERT(sink);
13158 if (d->method_->dest_handlers_) {
13159 if (sink->handlers != d->method_->dest_handlers_)
13160 return NULL;
13161 }
13162 upb_sink_reset(&d->top->sink, sink->handlers, sink->closure);
13163
13164 /* If this fails, increase the value in decoder.h. */
13165 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
13166 UPB_PB_DECODER_SIZE);
13167 return d;
13168}
13169
13170uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
13171 return offset(d);
13172}
13173
13174const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
13175 return d->method_;
13176}
13177
13178upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d) {
13179 return &d->input_;
13180}
13181
13182size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) {
13183 return d->stack_size;
13184}
13185
13186bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
13187 UPB_ASSERT(d->top >= d->stack);
13188
13189 if (max < (size_t)(d->top - d->stack)) {
13190 /* Can't set a limit smaller than what we are currently at. */
13191 return false;
13192 }
13193
13194 if (max > d->stack_size) {
13195 /* Need to reallocate stack and callstack to accommodate. */
13196 size_t old_size = stacksize(d, d->stack_size);
13197 size_t new_size = stacksize(d, max);
13198 void *p = upb_env_realloc(d->env, d->stack, old_size, new_size);
13199 if (!p) {
13200 return false;
13201 }
13202 d->stack = p;
13203
13204 old_size = callstacksize(d, d->stack_size);
13205 new_size = callstacksize(d, max);
13206 p = upb_env_realloc(d->env, d->callstack, old_size, new_size);
13207 if (!p) {
13208 return false;
13209 }
13210 d->callstack = p;
13211
13212 d->stack_size = max;
13213 }
13214
13215 d->limit = d->stack + max - 1;
13216 return true;
13217}
13218/*
13219** upb::Encoder
13220**
13221** Since we are implementing pure handlers (ie. without any out-of-band access
13222** to pre-computed lengths), we have to buffer all submessages before we can
13223** emit even their first byte.
13224**
13225** Not knowing the size of submessages also means we can't write a perfect
13226** zero-copy implementation, even with buffering. Lengths are stored as
13227** varints, which means that we don't know how many bytes to reserve for the
13228** length until we know what the length is.
13229**
13230** This leaves us with three main choices:
13231**
13232** 1. buffer all submessage data in a temporary buffer, then copy it exactly
13233** once into the output buffer.
13234**
13235** 2. attempt to buffer data directly into the output buffer, estimating how
13236** many bytes each length will take. When our guesses are wrong, use
13237** memmove() to grow or shrink the allotted space.
13238**
13239** 3. buffer directly into the output buffer, allocating a max length
13240** ahead-of-time for each submessage length. If we overallocated, we waste
13241** space, but no memcpy() or memmove() is required. This approach requires
13242** defining a maximum size for submessages and rejecting submessages that
13243** exceed that size.
13244**
13245** (2) and (3) have the potential to have better performance, but they are more
13246** complicated and subtle to implement:
13247**
13248** (3) requires making an arbitrary choice of the maximum message size; it
13249** wastes space when submessages are shorter than this and fails
13250** completely when they are longer. This makes it more finicky and
13251** requires configuration based on the input. It also makes it impossible
13252** to perfectly match the output of reference encoders that always use the
13253** optimal amount of space for each length.
13254**
13255** (2) requires guessing the the size upfront, and if multiple lengths are
13256** guessed wrong the minimum required number of memmove() operations may
13257** be complicated to compute correctly. Implemented properly, it may have
13258** a useful amortized or average cost, but more investigation is required
13259** to determine this and what the optimal algorithm is to achieve it.
13260**
13261** (1) makes you always pay for exactly one copy, but its implementation is
13262** the simplest and its performance is predictable.
13263**
13264** So for now, we implement (1) only. If we wish to optimize later, we should
13265** be able to do it without affecting users.
13266**
13267** The strategy is to buffer the segments of data that do *not* depend on
13268** unknown lengths in one buffer, and keep a separate buffer of segment pointers
13269** and lengths. When the top-level submessage ends, we can go beginning to end,
13270** alternating the writing of lengths with memcpy() of the rest of the data.
13271** At the top level though, no buffering is required.
13272*/
13273
13274
13275
13276/* The output buffer is divided into segments; a segment is a string of data
13277 * that is "ready to go" -- it does not need any varint lengths inserted into
13278 * the middle. The seams between segments are where varints will be inserted
13279 * once they are known.
13280 *
13281 * We also use the concept of a "run", which is a range of encoded bytes that
13282 * occur at a single submessage level. Every segment contains one or more runs.
13283 *
13284 * A segment can span messages. Consider:
13285 *
13286 * .--Submessage lengths---------.
13287 * | | |
13288 * | V V
13289 * V | |--------------- | |-----------------
13290 * Submessages: | |-----------------------------------------------
13291 * Top-level msg: ------------------------------------------------------------
13292 *
13293 * Segments: ----- ------------------- -----------------
13294 * Runs: *---- *--------------*--- *----------------
13295 * (* marks the start)
13296 *
13297 * Note that the top-level menssage is not in any segment because it does not
13298 * have any length preceding it.
13299 *
13300 * A segment is only interrupted when another length needs to be inserted. So
13301 * observe how the second segment spans both the inner submessage and part of
13302 * the next enclosing message. */
13303typedef struct {
13304 uint32_t msglen; /* The length to varint-encode before this segment. */
13305 uint32_t seglen; /* Length of the segment. */
13306} upb_pb_encoder_segment;
13307
13308struct upb_pb_encoder {
13309 upb_env *env;
13310
13311 /* Our input and output. */
13312 upb_sink input_;
13313 upb_bytessink *output_;
13314
13315 /* The "subclosure" -- used as the inner closure as part of the bytessink
13316 * protocol. */
13317 void *subc;
13318
13319 /* The output buffer and limit, and our current write position. "buf"
13320 * initially points to "initbuf", but is dynamically allocated if we need to
13321 * grow beyond the initial size. */
13322 char *buf, *ptr, *limit;
13323
13324 /* The beginning of the current run, or undefined if we are at the top
13325 * level. */
13326 char *runbegin;
13327
13328 /* The list of segments we are accumulating. */
13329 upb_pb_encoder_segment *segbuf, *segptr, *seglimit;
13330
13331 /* The stack of enclosing submessages. Each entry in the stack points to the
13332 * segment where this submessage's length is being accumulated. */
13333 int *stack, *top, *stacklimit;
13334
13335 /* Depth of startmsg/endmsg calls. */
13336 int depth;
13337};
13338
13339/* low-level buffering ********************************************************/
13340
13341/* Low-level functions for interacting with the output buffer. */
13342
13343/* TODO(haberman): handle pushback */
13344static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) {
13345 size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL);
13346 UPB_ASSERT(n == len);
13347}
13348
13349static upb_pb_encoder_segment *top(upb_pb_encoder *e) {
13350 return &e->segbuf[*e->top];
13351}
13352
13353/* Call to ensure that at least "bytes" bytes are available for writing at
13354 * e->ptr. Returns false if the bytes could not be allocated. */
13355static bool reserve(upb_pb_encoder *e, size_t bytes) {
13356 if ((size_t)(e->limit - e->ptr) < bytes) {
13357 /* Grow buffer. */
13358 char *new_buf;
13359 size_t needed = bytes + (e->ptr - e->buf);
13360 size_t old_size = e->limit - e->buf;
13361
13362 size_t new_size = old_size;
13363
13364 while (new_size < needed) {
13365 new_size *= 2;
13366 }
13367
13368 new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
13369
13370 if (new_buf == NULL) {
13371 return false;
13372 }
13373
13374 e->ptr = new_buf + (e->ptr - e->buf);
13375 e->runbegin = new_buf + (e->runbegin - e->buf);
13376 e->limit = new_buf + new_size;
13377 e->buf = new_buf;
13378 }
13379
13380 return true;
13381}
13382
13383/* Call when "bytes" bytes have been writte at e->ptr. The caller *must* have
13384 * previously called reserve() with at least this many bytes. */
13385static void encoder_advance(upb_pb_encoder *e, size_t bytes) {
13386 UPB_ASSERT((size_t)(e->limit - e->ptr) >= bytes);
13387 e->ptr += bytes;
13388}
13389
13390/* Call when all of the bytes for a handler have been written. Flushes the
13391 * bytes if possible and necessary, returning false if this failed. */
13392static bool commit(upb_pb_encoder *e) {
13393 if (!e->top) {
13394 /* We aren't inside a delimited region. Flush our accumulated bytes to
13395 * the output.
13396 *
13397 * TODO(haberman): in the future we may want to delay flushing for
13398 * efficiency reasons. */
13399 putbuf(e, e->buf, e->ptr - e->buf);
13400 e->ptr = e->buf;
13401 }
13402
13403 return true;
13404}
13405
13406/* Writes the given bytes to the buffer, handling reserve/advance. */
13407static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) {
13408 if (!reserve(e, len)) {
13409 return false;
13410 }
13411
13412 memcpy(e->ptr, data, len);
13413 encoder_advance(e, len);
13414 return true;
13415}
13416
13417/* Finish the current run by adding the run totals to the segment and message
13418 * length. */
13419static void accumulate(upb_pb_encoder *e) {
13420 size_t run_len;
13421 UPB_ASSERT(e->ptr >= e->runbegin);
13422 run_len = e->ptr - e->runbegin;
13423 e->segptr->seglen += run_len;
13424 top(e)->msglen += run_len;
13425 e->runbegin = e->ptr;
13426}
13427
13428/* Call to indicate the start of delimited region for which the full length is
13429 * not yet known. All data will be buffered until the length is known.
13430 * Delimited regions may be nested; their lengths will all be tracked properly. */
13431static bool start_delim(upb_pb_encoder *e) {
13432 if (e->top) {
13433 /* We are already buffering, advance to the next segment and push it on the
13434 * stack. */
13435 accumulate(e);
13436
13437 if (++e->top == e->stacklimit) {
13438 /* TODO(haberman): grow stack? */
13439 return false;
13440 }
13441
13442 if (++e->segptr == e->seglimit) {
13443 /* Grow segment buffer. */
13444 size_t old_size =
13445 (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
13446 size_t new_size = old_size * 2;
13447 upb_pb_encoder_segment *new_buf =
13448 upb_env_realloc(e->env, e->segbuf, old_size, new_size);
13449
13450 if (new_buf == NULL) {
13451 return false;
13452 }
13453
13454 e->segptr = new_buf + (e->segptr - e->segbuf);
13455 e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment));
13456 e->segbuf = new_buf;
13457 }
13458 } else {
13459 /* We were previously at the top level, start buffering. */
13460 e->segptr = e->segbuf;
13461 e->top = e->stack;
13462 e->runbegin = e->ptr;
13463 }
13464
13465 *e->top = e->segptr - e->segbuf;
13466 e->segptr->seglen = 0;
13467 e->segptr->msglen = 0;
13468
13469 return true;
13470}
13471
13472/* Call to indicate the end of a delimited region. We now know the length of
13473 * the delimited region. If we are not nested inside any other delimited
13474 * regions, we can now emit all of the buffered data we accumulated. */
13475static bool end_delim(upb_pb_encoder *e) {
13476 size_t msglen;
13477 accumulate(e);
13478 msglen = top(e)->msglen;
13479
13480 if (e->top == e->stack) {
13481 /* All lengths are now available, emit all buffered data. */
13482 char buf[UPB_PB_VARINT_MAX_LEN];
13483 upb_pb_encoder_segment *s;
13484 const char *ptr = e->buf;
13485 for (s = e->segbuf; s <= e->segptr; s++) {
13486 size_t lenbytes = upb_vencode64(s->msglen, buf);
13487 putbuf(e, buf, lenbytes);
13488 putbuf(e, ptr, s->seglen);
13489 ptr += s->seglen;
13490 }
13491
13492 e->ptr = e->buf;
13493 e->top = NULL;
13494 } else {
13495 /* Need to keep buffering; propagate length info into enclosing
13496 * submessages. */
13497 --e->top;
13498 top(e)->msglen += msglen + upb_varint_size(msglen);
13499 }
13500
13501 return true;
13502}
13503
13504
13505/* tag_t **********************************************************************/
13506
13507/* A precomputed (pre-encoded) tag and length. */
13508
13509typedef struct {
13510 uint8_t bytes;
13511 char tag[7];
13512} tag_t;
13513
13514/* Allocates a new tag for this field, and sets it in these handlerattr. */
13515static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
13516 upb_handlerattr *attr) {
13517 uint32_t n = upb_fielddef_number(f);
13518
13519 tag_t *tag = upb_gmalloc(sizeof(tag_t));
13520 tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
13521
13522 upb_handlerattr_init(attr);
13523 upb_handlerattr_sethandlerdata(attr, tag);
13524 upb_handlers_addcleanup(h, tag, upb_gfree);
13525}
13526
13527static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
13528 return encode_bytes(e, tag->tag, tag->bytes);
13529}
13530
13531
13532/* encoding of wire types *****************************************************/
13533
13534static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) {
13535 /* TODO(haberman): byte-swap for big endian. */
13536 return encode_bytes(e, &val, sizeof(uint64_t));
13537}
13538
13539static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) {
13540 /* TODO(haberman): byte-swap for big endian. */
13541 return encode_bytes(e, &val, sizeof(uint32_t));
13542}
13543
13544static bool encode_varint(upb_pb_encoder *e, uint64_t val) {
13545 if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) {
13546 return false;
13547 }
13548
13549 encoder_advance(e, upb_vencode64(val, e->ptr));
13550 return true;
13551}
13552
13553static uint64_t dbl2uint64(double d) {
13554 uint64_t ret;
13555 memcpy(&ret, &d, sizeof(uint64_t));
13556 return ret;
13557}
13558
13559static uint32_t flt2uint32(float d) {
13560 uint32_t ret;
13561 memcpy(&ret, &d, sizeof(uint32_t));
13562 return ret;
13563}
13564
13565
13566/* encoding of proto types ****************************************************/
13567
13568static bool startmsg(void *c, const void *hd) {
13569 upb_pb_encoder *e = c;
13570 UPB_UNUSED(hd);
13571 if (e->depth++ == 0) {
13572 upb_bytessink_start(e->output_, 0, &e->subc);
13573 }
13574 return true;
13575}
13576
13577static bool endmsg(void *c, const void *hd, upb_status *status) {
13578 upb_pb_encoder *e = c;
13579 UPB_UNUSED(hd);
13580 UPB_UNUSED(status);
13581 if (--e->depth == 0) {
13582 upb_bytessink_end(e->output_);
13583 }
13584 return true;
13585}
13586
13587static void *encode_startdelimfield(void *c, const void *hd) {
13588 bool ok = encode_tag(c, hd) && commit(c) && start_delim(c);
13589 return ok ? c : UPB_BREAK;
13590}
13591
13592static bool encode_unknown(void *c, const void *hd, const char *buf,
13593 size_t len) {
13594 UPB_UNUSED(hd);
13595 return encode_bytes(c, buf, len) && commit(c);
13596}
13597
13598static bool encode_enddelimfield(void *c, const void *hd) {
13599 UPB_UNUSED(hd);
13600 return end_delim(c);
13601}
13602
13603static void *encode_startgroup(void *c, const void *hd) {
13604 return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK;
13605}
13606
13607static bool encode_endgroup(void *c, const void *hd) {
13608 return encode_tag(c, hd) && commit(c);
13609}
13610
13611static void *encode_startstr(void *c, const void *hd, size_t size_hint) {
13612 UPB_UNUSED(size_hint);
13613 return encode_startdelimfield(c, hd);
13614}
13615
13616static size_t encode_strbuf(void *c, const void *hd, const char *buf,
13617 size_t len, const upb_bufhandle *h) {
13618 UPB_UNUSED(hd);
13619 UPB_UNUSED(h);
13620 return encode_bytes(c, buf, len) ? len : 0;
13621}
13622
13623#define T(type, ctype, convert, encode) \
13624 static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \
13625 return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e); \
13626 } \
13627 static bool encode_packed_##type(void *e, const void *hd, ctype val) { \
13628 UPB_UNUSED(hd); \
13629 return encode(e, (convert)(val)); \
13630 }
13631
13632T(double, double, dbl2uint64, encode_fixed64)
13633T(float, float, flt2uint32, encode_fixed32)
13634T(int64, int64_t, uint64_t, encode_varint)
13635T(int32, int32_t, int64_t, encode_varint)
13636T(fixed64, uint64_t, uint64_t, encode_fixed64)
13637T(fixed32, uint32_t, uint32_t, encode_fixed32)
13638T(bool, bool, bool, encode_varint)
13639T(uint32, uint32_t, uint32_t, encode_varint)
13640T(uint64, uint64_t, uint64_t, encode_varint)
13641T(enum, int32_t, uint32_t, encode_varint)
13642T(sfixed32, int32_t, uint32_t, encode_fixed32)
13643T(sfixed64, int64_t, uint64_t, encode_fixed64)
13644T(sint32, int32_t, upb_zzenc_32, encode_varint)
13645T(sint64, int64_t, upb_zzenc_64, encode_varint)
13646
13647#undef T
13648
13649
13650/* code to build the handlers *************************************************/
13651
13652static void newhandlers_callback(const void *closure, upb_handlers *h) {
13653 const upb_msgdef *m;
13654 upb_msg_field_iter i;
13655
13656 UPB_UNUSED(closure);
13657
13658 upb_handlers_setstartmsg(h, startmsg, NULL);
13659 upb_handlers_setendmsg(h, endmsg, NULL);
13660 upb_handlers_setunknown(h, encode_unknown, NULL);
13661
13662 m = upb_handlers_msgdef(h);
13663 for(upb_msg_field_begin(&i, m);
13664 !upb_msg_field_done(&i);
13665 upb_msg_field_next(&i)) {
13666 const upb_fielddef *f = upb_msg_iter_field(&i);
13667 bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
13668 upb_fielddef_packed(f);
13669 upb_handlerattr attr;
13670 upb_wiretype_t wt =
13671 packed ? UPB_WIRE_TYPE_DELIMITED
13672 : upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
13673
13674 /* Pre-encode the tag for this field. */
13675 new_tag(h, f, wt, &attr);
13676
13677 if (packed) {
13678 upb_handlers_setstartseq(h, f, encode_startdelimfield, &attr);
13679 upb_handlers_setendseq(h, f, encode_enddelimfield, &attr);
13680 }
13681
13682#define T(upper, lower, upbtype) \
13683 case UPB_DESCRIPTOR_TYPE_##upper: \
13684 if (packed) { \
13685 upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \
13686 } else { \
13687 upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \
13688 } \
13689 break;
13690
13691 switch (upb_fielddef_descriptortype(f)) {
13692 T(DOUBLE, double, double);
13693 T(FLOAT, float, float);
13694 T(INT64, int64, int64);
13695 T(INT32, int32, int32);
13696 T(FIXED64, fixed64, uint64);
13697 T(FIXED32, fixed32, uint32);
13698 T(BOOL, bool, bool);
13699 T(UINT32, uint32, uint32);
13700 T(UINT64, uint64, uint64);
13701 T(ENUM, enum, int32);
13702 T(SFIXED32, sfixed32, int32);
13703 T(SFIXED64, sfixed64, int64);
13704 T(SINT32, sint32, int32);
13705 T(SINT64, sint64, int64);
13706 case UPB_DESCRIPTOR_TYPE_STRING:
13707 case UPB_DESCRIPTOR_TYPE_BYTES:
13708 upb_handlers_setstartstr(h, f, encode_startstr, &attr);
13709 upb_handlers_setendstr(h, f, encode_enddelimfield, &attr);
13710 upb_handlers_setstring(h, f, encode_strbuf, &attr);
13711 break;
13712 case UPB_DESCRIPTOR_TYPE_MESSAGE:
13713 upb_handlers_setstartsubmsg(h, f, encode_startdelimfield, &attr);
13714 upb_handlers_setendsubmsg(h, f, encode_enddelimfield, &attr);
13715 break;
13716 case UPB_DESCRIPTOR_TYPE_GROUP: {
13717 /* Endgroup takes a different tag (wire_type = END_GROUP). */
13718 upb_handlerattr attr2;
13719 new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2);
13720
13721 upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr);
13722 upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2);
13723
13724 upb_handlerattr_uninit(&attr2);
13725 break;
13726 }
13727 }
13728
13729#undef T
13730
13731 upb_handlerattr_uninit(&attr);
13732 }
13733}
13734
13735void upb_pb_encoder_reset(upb_pb_encoder *e) {
13736 e->segptr = NULL;
13737 e->top = NULL;
13738 e->depth = 0;
13739}
13740
13741
13742/* public API *****************************************************************/
13743
13744const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
13745 const void *owner) {
13746 return upb_handlers_newfrozen(m, owner, newhandlers_callback, NULL);
13747}
13748
13749upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
13750 upb_bytessink *output) {
13751 const size_t initial_bufsize = 256;
13752 const size_t initial_segbufsize = 16;
13753 /* TODO(haberman): make this configurable. */
13754 const size_t stack_size = 64;
13755#ifndef NDEBUG
13756 const size_t size_before = upb_env_bytesallocated(env);
13757#endif
13758
13759 upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder));
13760 if (!e) return NULL;
13761
13762 e->buf = upb_env_malloc(env, initial_bufsize);
13763 e->segbuf = upb_env_malloc(env, initial_segbufsize * sizeof(*e->segbuf));
13764 e->stack = upb_env_malloc(env, stack_size * sizeof(*e->stack));
13765
13766 if (!e->buf || !e->segbuf || !e->stack) {
13767 return NULL;
13768 }
13769
13770 e->limit = e->buf + initial_bufsize;
13771 e->seglimit = e->segbuf + initial_segbufsize;
13772 e->stacklimit = e->stack + stack_size;
13773
13774 upb_pb_encoder_reset(e);
13775 upb_sink_reset(&e->input_, h, e);
13776
13777 e->env = env;
13778 e->output_ = output;
13779 e->subc = output->closure;
13780 e->ptr = e->buf;
13781
13782 /* If this fails, increase the value in encoder.h. */
13783 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
13784 UPB_PB_ENCODER_SIZE);
13785 return e;
13786}
13787
13788upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
13789
13790
13791
13792upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
13793 upb_status *status) {
13794 /* Create handlers. */
13795 const upb_pbdecodermethod *decoder_m;
13796 const upb_handlers *reader_h = upb_descreader_newhandlers(&reader_h);
13797 upb_env env;
13798 upb_pbdecodermethodopts opts;
13799 upb_pbdecoder *decoder;
13800 upb_descreader *reader;
13801 bool ok;
13802 size_t i;
13803 upb_filedef **ret = NULL;
13804
13805 upb_pbdecodermethodopts_init(&opts, reader_h);
13806 decoder_m = upb_pbdecodermethod_new(&opts, &decoder_m);
13807
13808 upb_env_init(&env);
13809 upb_env_reporterrorsto(&env, status);
13810
13811 reader = upb_descreader_create(&env, reader_h);
13812 decoder = upb_pbdecoder_create(&env, decoder_m, upb_descreader_input(reader));
13813
13814 /* Push input data. */
13815 ok = upb_bufsrc_putbuf(buf, n, upb_pbdecoder_input(decoder));
13816
13817 if (!ok) {
13818 goto cleanup;
13819 }
13820
13821 ret = upb_gmalloc(sizeof (*ret) * (upb_descreader_filecount(reader) + 1));
13822
13823 if (!ret) {
13824 goto cleanup;
13825 }
13826
13827 for (i = 0; i < upb_descreader_filecount(reader); i++) {
13828 ret[i] = upb_descreader_file(reader, i);
13829 upb_filedef_ref(ret[i], owner);
13830 }
13831
13832 ret[i] = NULL;
13833
13834cleanup:
13835 upb_env_uninit(&env);
13836 upb_handlers_unref(reader_h, &reader_h);
13837 upb_pbdecodermethod_unref(decoder_m, &decoder_m);
13838 return ret;
13839}
13840/*
13841 * upb::pb::TextPrinter
13842 *
13843 * OPT: This is not optimized at all. It uses printf() which parses the format
13844 * string every time, and it allocates memory for every put.
13845 */
13846
13847
13848#include <ctype.h>
13849#include <float.h>
13850#include <inttypes.h>
13851#include <stdarg.h>
13852#include <stdio.h>
13853#include <string.h>
13854
13855
13856struct upb_textprinter {
13857 upb_sink input_;
13858 upb_bytessink *output_;
13859 int indent_depth_;
13860 bool single_line_;
13861 void *subc;
13862};
13863
13864#define CHECK(x) if ((x) < 0) goto err;
13865
13866static const char *shortname(const char *longname) {
13867 const char *last = strrchr(longname, '.');
13868 return last ? last + 1 : longname;
13869}
13870
13871static int indent(upb_textprinter *p) {
13872 int i;
13873 if (!p->single_line_)
13874 for (i = 0; i < p->indent_depth_; i++)
13875 upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL);
13876 return 0;
13877}
13878
13879static int endfield(upb_textprinter *p) {
13880 const char ch = (p->single_line_ ? ' ' : '\n');
13881 upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL);
13882 return 0;
13883}
13884
13885static int putescaped(upb_textprinter *p, const char *buf, size_t len,
13886 bool preserve_utf8) {
13887 /* Based on CEscapeInternal() from Google's protobuf release. */
13888 char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf);
13889 const char *end = buf + len;
13890
13891 /* I think hex is prettier and more useful, but proto2 uses octal; should
13892 * investigate whether it can parse hex also. */
13893 const bool use_hex = false;
13894 bool last_hex_escape = false; /* true if last output char was \xNN */
13895
13896 for (; buf < end; buf++) {
13897 bool is_hex_escape;
13898
13899 if (dstend - dst < 4) {
13900 upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
13901 dst = dstbuf;
13902 }
13903
13904 is_hex_escape = false;
13905 switch (*buf) {
13906 case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break;
13907 case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break;
13908 case '\t': *(dst++) = '\\'; *(dst++) = 't'; break;
13909 case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break;
13910 case '\'': *(dst++) = '\\'; *(dst++) = '\''; break;
13911 case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break;
13912 default:
13913 /* Note that if we emit \xNN and the buf character after that is a hex
13914 * digit then that digit must be escaped too to prevent it being
13915 * interpreted as part of the character code by C. */
13916 if ((!preserve_utf8 || (uint8_t)*buf < 0x80) &&
13917 (!isprint(*buf) || (last_hex_escape && isxdigit(*buf)))) {
13918 sprintf(dst, (use_hex ? "\\x%02x" : "\\%03o"), (uint8_t)*buf);
13919 is_hex_escape = use_hex;
13920 dst += 4;
13921 } else {
13922 *(dst++) = *buf; break;
13923 }
13924 }
13925 last_hex_escape = is_hex_escape;
13926 }
13927 /* Flush remaining data. */
13928 upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
13929 return 0;
13930}
13931
13932bool putf(upb_textprinter *p, const char *fmt, ...) {
13933 va_list args;
13934 va_list args_copy;
13935 char *str;
13936 int written;
13937 int len;
13938 bool ok;
13939
13940 va_start(args, fmt);
13941
13942 /* Run once to get the length of the string. */
13943 _upb_va_copy(args_copy, args);
13944 len = _upb_vsnprintf(NULL, 0, fmt, args_copy);
13945 va_end(args_copy);
13946
13947 /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
13948 str = upb_gmalloc(len + 1);
13949 if (!str) return false;
13950 written = vsprintf(str, fmt, args);
13951 va_end(args);
13952 UPB_ASSERT(written == len);
13953
13954 ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
13955 upb_gfree(str);
13956 return ok;
13957}
13958
13959
13960/* handlers *******************************************************************/
13961
13962static bool textprinter_startmsg(void *c, const void *hd) {
13963 upb_textprinter *p = c;
13964 UPB_UNUSED(hd);
13965 if (p->indent_depth_ == 0) {
13966 upb_bytessink_start(p->output_, 0, &p->subc);
13967 }
13968 return true;
13969}
13970
13971static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) {
13972 upb_textprinter *p = c;
13973 UPB_UNUSED(hd);
13974 UPB_UNUSED(s);
13975 if (p->indent_depth_ == 0) {
13976 upb_bytessink_end(p->output_);
13977 }
13978 return true;
13979}
13980
13981#define TYPE(name, ctype, fmt) \
13982 static bool textprinter_put ## name(void *closure, const void *handler_data, \
13983 ctype val) { \
13984 upb_textprinter *p = closure; \
13985 const upb_fielddef *f = handler_data; \
13986 CHECK(indent(p)); \
13987 putf(p, "%s: " fmt, upb_fielddef_name(f), val); \
13988 CHECK(endfield(p)); \
13989 return true; \
13990 err: \
13991 return false; \
13992}
13993
13994static bool textprinter_putbool(void *closure, const void *handler_data,
13995 bool val) {
13996 upb_textprinter *p = closure;
13997 const upb_fielddef *f = handler_data;
13998 CHECK(indent(p));
13999 putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false");
14000 CHECK(endfield(p));
14001 return true;
14002err:
14003 return false;
14004}
14005
14006#define STRINGIFY_HELPER(x) #x
14007#define STRINGIFY_MACROVAL(x) STRINGIFY_HELPER(x)
14008
14009TYPE(int32, int32_t, "%" PRId32)
14010TYPE(int64, int64_t, "%" PRId64)
14011TYPE(uint32, uint32_t, "%" PRIu32)
14012TYPE(uint64, uint64_t, "%" PRIu64)
14013TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g")
14014TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g")
14015
14016#undef TYPE
14017
14018/* Output a symbolic value from the enum if found, else just print as int32. */
14019static bool textprinter_putenum(void *closure, const void *handler_data,
14020 int32_t val) {
14021 upb_textprinter *p = closure;
14022 const upb_fielddef *f = handler_data;
14023 const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
14024 const char *label = upb_enumdef_iton(enum_def, val);
14025 if (label) {
14026 indent(p);
14027 putf(p, "%s: %s", upb_fielddef_name(f), label);
14028 endfield(p);
14029 } else {
14030 if (!textprinter_putint32(closure, handler_data, val))
14031 return false;
14032 }
14033 return true;
14034}
14035
14036static void *textprinter_startstr(void *closure, const void *handler_data,
14037 size_t size_hint) {
14038 upb_textprinter *p = closure;
14039 const upb_fielddef *f = handler_data;
14040 UPB_UNUSED(size_hint);
14041 indent(p);
14042 putf(p, "%s: \"", upb_fielddef_name(f));
14043 return p;
14044}
14045
14046static bool textprinter_endstr(void *closure, const void *handler_data) {
14047 upb_textprinter *p = closure;
14048 UPB_UNUSED(handler_data);
14049 putf(p, "\"");
14050 endfield(p);
14051 return true;
14052}
14053
14054static size_t textprinter_putstr(void *closure, const void *hd, const char *buf,
14055 size_t len, const upb_bufhandle *handle) {
14056 upb_textprinter *p = closure;
14057 const upb_fielddef *f = hd;
14058 UPB_UNUSED(handle);
14059 CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING));
14060 return len;
14061err:
14062 return 0;
14063}
14064
14065static void *textprinter_startsubmsg(void *closure, const void *handler_data) {
14066 upb_textprinter *p = closure;
14067 const char *name = handler_data;
14068 CHECK(indent(p));
14069 putf(p, "%s {%c", name, p->single_line_ ? ' ' : '\n');
14070 p->indent_depth_++;
14071 return p;
14072err:
14073 return UPB_BREAK;
14074}
14075
14076static bool textprinter_endsubmsg(void *closure, const void *handler_data) {
14077 upb_textprinter *p = closure;
14078 UPB_UNUSED(handler_data);
14079 p->indent_depth_--;
14080 CHECK(indent(p));
14081 upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL);
14082 CHECK(endfield(p));
14083 return true;
14084err:
14085 return false;
14086}
14087
14088static void onmreg(const void *c, upb_handlers *h) {
14089 const upb_msgdef *m = upb_handlers_msgdef(h);
14090 upb_msg_field_iter i;
14091 UPB_UNUSED(c);
14092
14093 upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
14094 upb_handlers_setendmsg(h, textprinter_endmsg, NULL);
14095
14096 for(upb_msg_field_begin(&i, m);
14097 !upb_msg_field_done(&i);
14098 upb_msg_field_next(&i)) {
14099 upb_fielddef *f = upb_msg_iter_field(&i);
14100 upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
14101 upb_handlerattr_sethandlerdata(&attr, f);
14102 switch (upb_fielddef_type(f)) {
14103 case UPB_TYPE_INT32:
14104 upb_handlers_setint32(h, f, textprinter_putint32, &attr);
14105 break;
14106 case UPB_TYPE_INT64:
14107 upb_handlers_setint64(h, f, textprinter_putint64, &attr);
14108 break;
14109 case UPB_TYPE_UINT32:
14110 upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
14111 break;
14112 case UPB_TYPE_UINT64:
14113 upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
14114 break;
14115 case UPB_TYPE_FLOAT:
14116 upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
14117 break;
14118 case UPB_TYPE_DOUBLE:
14119 upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
14120 break;
14121 case UPB_TYPE_BOOL:
14122 upb_handlers_setbool(h, f, textprinter_putbool, &attr);
14123 break;
14124 case UPB_TYPE_STRING:
14125 case UPB_TYPE_BYTES:
14126 upb_handlers_setstartstr(h, f, textprinter_startstr, &attr);
14127 upb_handlers_setstring(h, f, textprinter_putstr, &attr);
14128 upb_handlers_setendstr(h, f, textprinter_endstr, &attr);
14129 break;
14130 case UPB_TYPE_MESSAGE: {
14131 const char *name =
14132 upb_fielddef_istagdelim(f)
14133 ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
14134 : upb_fielddef_name(f);
14135 upb_handlerattr_sethandlerdata(&attr, name);
14136 upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
14137 upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
14138 break;
14139 }
14140 case UPB_TYPE_ENUM:
14141 upb_handlers_setint32(h, f, textprinter_putenum, &attr);
14142 break;
14143 }
14144 }
14145}
14146
14147static void textprinter_reset(upb_textprinter *p, bool single_line) {
14148 p->single_line_ = single_line;
14149 p->indent_depth_ = 0;
14150}
14151
14152
14153/* Public API *****************************************************************/
14154
14155upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
14156 upb_bytessink *output) {
14157 upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter));
14158 if (!p) return NULL;
14159
14160 p->output_ = output;
14161 upb_sink_reset(&p->input_, h, p);
14162 textprinter_reset(p, false);
14163
14164 return p;
14165}
14166
14167const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
14168 const void *owner) {
14169 return upb_handlers_newfrozen(m, owner, &onmreg, NULL);
14170}
14171
14172upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
14173
14174void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) {
14175 p->single_line_ = single_line;
14176}
14177
14178
14179/* Index is descriptor type. */
14180const uint8_t upb_pb_native_wire_types[] = {
14181 UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
14182 UPB_WIRE_TYPE_64BIT, /* DOUBLE */
14183 UPB_WIRE_TYPE_32BIT, /* FLOAT */
14184 UPB_WIRE_TYPE_VARINT, /* INT64 */
14185 UPB_WIRE_TYPE_VARINT, /* UINT64 */
14186 UPB_WIRE_TYPE_VARINT, /* INT32 */
14187 UPB_WIRE_TYPE_64BIT, /* FIXED64 */
14188 UPB_WIRE_TYPE_32BIT, /* FIXED32 */
14189 UPB_WIRE_TYPE_VARINT, /* BOOL */
14190 UPB_WIRE_TYPE_DELIMITED, /* STRING */
14191 UPB_WIRE_TYPE_START_GROUP, /* GROUP */
14192 UPB_WIRE_TYPE_DELIMITED, /* MESSAGE */
14193 UPB_WIRE_TYPE_DELIMITED, /* BYTES */
14194 UPB_WIRE_TYPE_VARINT, /* UINT32 */
14195 UPB_WIRE_TYPE_VARINT, /* ENUM */
14196 UPB_WIRE_TYPE_32BIT, /* SFIXED32 */
14197 UPB_WIRE_TYPE_64BIT, /* SFIXED64 */
14198 UPB_WIRE_TYPE_VARINT, /* SINT32 */
14199 UPB_WIRE_TYPE_VARINT, /* SINT64 */
14200};
14201
14202/* A basic branch-based decoder, uses 32-bit values to get good performance
14203 * on 32-bit architectures (but performs well on 64-bits also).
14204 * This scheme comes from the original Google Protobuf implementation
14205 * (proto2). */
14206upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r) {
14207 upb_decoderet err = {NULL, 0};
14208 const char *p = r.p;
14209 uint32_t low = (uint32_t)r.val;
14210 uint32_t high = 0;
14211 uint32_t b;
14212 b = *(p++); low |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
14213 b = *(p++); low |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
14214 b = *(p++); low |= (b & 0x7fU) << 28;
14215 high = (b & 0x7fU) >> 4; if (!(b & 0x80)) goto done;
14216 b = *(p++); high |= (b & 0x7fU) << 3; if (!(b & 0x80)) goto done;
14217 b = *(p++); high |= (b & 0x7fU) << 10; if (!(b & 0x80)) goto done;
14218 b = *(p++); high |= (b & 0x7fU) << 17; if (!(b & 0x80)) goto done;
14219 b = *(p++); high |= (b & 0x7fU) << 24; if (!(b & 0x80)) goto done;
14220 b = *(p++); high |= (b & 0x7fU) << 31; if (!(b & 0x80)) goto done;
14221 return err;
14222
14223done:
14224 r.val = ((uint64_t)high << 32) | low;
14225 r.p = p;
14226 return r;
14227}
14228
14229/* Like the previous, but uses 64-bit values. */
14230upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r) {
14231 const char *p = r.p;
14232 uint64_t val = r.val;
14233 uint64_t b;
14234 upb_decoderet err = {NULL, 0};
14235 b = *(p++); val |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
14236 b = *(p++); val |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
14237 b = *(p++); val |= (b & 0x7fU) << 28; if (!(b & 0x80)) goto done;
14238 b = *(p++); val |= (b & 0x7fU) << 35; if (!(b & 0x80)) goto done;
14239 b = *(p++); val |= (b & 0x7fU) << 42; if (!(b & 0x80)) goto done;
14240 b = *(p++); val |= (b & 0x7fU) << 49; if (!(b & 0x80)) goto done;
14241 b = *(p++); val |= (b & 0x7fU) << 56; if (!(b & 0x80)) goto done;
14242 b = *(p++); val |= (b & 0x7fU) << 63; if (!(b & 0x80)) goto done;
14243 return err;
14244
14245done:
14246 r.val = val;
14247 r.p = p;
14248 return r;
14249}
14250
14251#line 1 "upb/json/parser.rl"
14252/*
14253** upb::json::Parser (upb_json_parser)
14254**
14255** A parser that uses the Ragel State Machine Compiler to generate
14256** the finite automata.
14257**
14258** Ragel only natively handles regular languages, but we can manually
14259** program it a bit to handle context-free languages like JSON, by using
14260** the "fcall" and "fret" constructs.
14261**
14262** This parser can handle the basics, but needs several things to be fleshed
14263** out:
14264**
14265** - handling of unicode escape sequences (including high surrogate pairs).
14266** - properly check and report errors for unknown fields, stack overflow,
14267** improper array nesting (or lack of nesting).
14268** - handling of base64 sequences with padding characters.
14269** - handling of push-back (non-success returns from sink functions).
14270** - handling of keys/escape-sequences/etc that span input buffers.
14271*/
14272
14273#include <errno.h>
14274#include <float.h>
14275#include <math.h>
14276#include <stdint.h>
14277#include <stdlib.h>
14278#include <string.h>
14279
14280
14281#define UPB_JSON_MAX_DEPTH 64
14282
14283typedef struct {
14284 upb_sink sink;
14285
14286 /* The current message in which we're parsing, and the field whose value we're
14287 * expecting next. */
14288 const upb_msgdef *m;
14289 const upb_fielddef *f;
14290
14291 /* The table mapping json name to fielddef for this message. */
14292 upb_strtable *name_table;
14293
14294 /* We are in a repeated-field context, ready to emit mapentries as
14295 * submessages. This flag alters the start-of-object (open-brace) behavior to
14296 * begin a sequence of mapentry messages rather than a single submessage. */
14297 bool is_map;
14298
14299 /* We are in a map-entry message context. This flag is set when parsing the
14300 * value field of a single map entry and indicates to all value-field parsers
14301 * (subobjects, strings, numbers, and bools) that the map-entry submessage
14302 * should end as soon as the value is parsed. */
14303 bool is_mapentry;
14304
14305 /* If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
14306 * message's map field that we're currently parsing. This differs from |f|
14307 * because |f| is the field in the *current* message (i.e., the map-entry
14308 * message itself), not the parent's field that leads to this map. */
14309 const upb_fielddef *mapfield;
14310} upb_jsonparser_frame;
14311
14312struct upb_json_parser {
14313 upb_env *env;
14314 const upb_json_parsermethod *method;
14315 upb_bytessink input_;
14316
14317 /* Stack to track the JSON scopes we are in. */
14318 upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH];
14319 upb_jsonparser_frame *top;
14320 upb_jsonparser_frame *limit;
14321
14322 upb_status status;
14323
14324 /* Ragel's internal parsing stack for the parsing state machine. */
14325 int current_state;
14326 int parser_stack[UPB_JSON_MAX_DEPTH];
14327 int parser_top;
14328
14329 /* The handle for the current buffer. */
14330 const upb_bufhandle *handle;
14331
14332 /* Accumulate buffer. See details in parser.rl. */
14333 const char *accumulated;
14334 size_t accumulated_len;
14335 char *accumulate_buf;
14336 size_t accumulate_buf_size;
14337
14338 /* Multi-part text data. See details in parser.rl. */
14339 int multipart_state;
14340 upb_selector_t string_selector;
14341
14342 /* Input capture. See details in parser.rl. */
14343 const char *capture;
14344
14345 /* Intermediate result of parsing a unicode escape sequence. */
14346 uint32_t digit;
14347};
14348
14349struct upb_json_parsermethod {
14350 upb_refcounted base;
14351
14352 upb_byteshandler input_handler_;
14353
14354 /* Mainly for the purposes of refcounting, so all the fielddefs we point
14355 * to stay alive. */
14356 const upb_msgdef *msg;
14357
14358 /* Keys are upb_msgdef*, values are upb_strtable (json_name -> fielddef) */
14359 upb_inttable name_tables;
14360};
14361
14362#define PARSER_CHECK_RETURN(x) if (!(x)) return false
14363
14364/* Used to signal that a capture has been suspended. */
14365static char suspend_capture;
14366
14367static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
14368 upb_handlertype_t type) {
14369 upb_selector_t sel;
14370 bool ok = upb_handlers_getselector(p->top->f, type, &sel);
14371 UPB_ASSERT(ok);
14372 return sel;
14373}
14374
14375static upb_selector_t parser_getsel(upb_json_parser *p) {
14376 return getsel_for_handlertype(
14377 p, upb_handlers_getprimitivehandlertype(p->top->f));
14378}
14379
14380static bool check_stack(upb_json_parser *p) {
14381 if ((p->top + 1) == p->limit) {
14382 upb_status_seterrmsg(&p->status, "Nesting too deep");
14383 upb_env_reporterror(p->env, &p->status);
14384 return false;
14385 }
14386
14387 return true;
14388}
14389
14390static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
14391 upb_value v;
14392 bool ok = upb_inttable_lookupptr(&p->method->name_tables, frame->m, &v);
14393 UPB_ASSERT(ok);
14394 frame->name_table = upb_value_getptr(v);
14395}
14396
14397/* There are GCC/Clang built-ins for overflow checking which we could start
14398 * using if there was any performance benefit to it. */
14399
14400static bool checked_add(size_t a, size_t b, size_t *c) {
14401 if (SIZE_MAX - a < b) return false;
14402 *c = a + b;
14403 return true;
14404}
14405
14406static size_t saturating_multiply(size_t a, size_t b) {
14407 /* size_t is unsigned, so this is defined behavior even on overflow. */
14408 size_t ret = a * b;
14409 if (b != 0 && ret / b != a) {
14410 ret = SIZE_MAX;
14411 }
14412 return ret;
14413}
14414
14415
14416/* Base64 decoding ************************************************************/
14417
14418/* TODO(haberman): make this streaming. */
14419
14420static const signed char b64table[] = {
14421 -1, -1, -1, -1, -1, -1, -1, -1,
14422 -1, -1, -1, -1, -1, -1, -1, -1,
14423 -1, -1, -1, -1, -1, -1, -1, -1,
14424 -1, -1, -1, -1, -1, -1, -1, -1,
14425 -1, -1, -1, -1, -1, -1, -1, -1,
14426 -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */,
14427 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
14428 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1,
14429 -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
14430 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
14431 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
14432 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1,
14433 -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
14434 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
14435 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
14436 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1,
14437 -1, -1, -1, -1, -1, -1, -1, -1,
14438 -1, -1, -1, -1, -1, -1, -1, -1,
14439 -1, -1, -1, -1, -1, -1, -1, -1,
14440 -1, -1, -1, -1, -1, -1, -1, -1,
14441 -1, -1, -1, -1, -1, -1, -1, -1,
14442 -1, -1, -1, -1, -1, -1, -1, -1,
14443 -1, -1, -1, -1, -1, -1, -1, -1,
14444 -1, -1, -1, -1, -1, -1, -1, -1,
14445 -1, -1, -1, -1, -1, -1, -1, -1,
14446 -1, -1, -1, -1, -1, -1, -1, -1,
14447 -1, -1, -1, -1, -1, -1, -1, -1,
14448 -1, -1, -1, -1, -1, -1, -1, -1,
14449 -1, -1, -1, -1, -1, -1, -1, -1,
14450 -1, -1, -1, -1, -1, -1, -1, -1,
14451 -1, -1, -1, -1, -1, -1, -1, -1,
14452 -1, -1, -1, -1, -1, -1, -1, -1
14453};
14454
14455/* Returns the table value sign-extended to 32 bits. Knowing that the upper
14456 * bits will be 1 for unrecognized characters makes it easier to check for
14457 * this error condition later (see below). */
14458int32_t b64lookup(unsigned char ch) { return b64table[ch]; }
14459
14460/* Returns true if the given character is not a valid base64 character or
14461 * padding. */
14462bool nonbase64(unsigned char ch) { return b64lookup(ch) == -1 && ch != '='; }
14463
14464static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
14465 size_t len) {
14466 const char *limit = ptr + len;
14467 for (; ptr < limit; ptr += 4) {
14468 uint32_t val;
14469 char output[3];
14470
14471 if (limit - ptr < 4) {
14472 upb_status_seterrf(&p->status,
14473 "Base64 input for bytes field not a multiple of 4: %s",
14474 upb_fielddef_name(p->top->f));
14475 upb_env_reporterror(p->env, &p->status);
14476 return false;
14477 }
14478
14479 val = b64lookup(ptr[0]) << 18 |
14480 b64lookup(ptr[1]) << 12 |
14481 b64lookup(ptr[2]) << 6 |
14482 b64lookup(ptr[3]);
14483
14484 /* Test the upper bit; returns true if any of the characters returned -1. */
14485 if (val & 0x80000000) {
14486 goto otherchar;
14487 }
14488
14489 output[0] = val >> 16;
14490 output[1] = (val >> 8) & 0xff;
14491 output[2] = val & 0xff;
14492 upb_sink_putstring(&p->top->sink, sel, output, 3, NULL);
14493 }
14494 return true;
14495
14496otherchar:
14497 if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) ||
14498 nonbase64(ptr[3]) ) {
14499 upb_status_seterrf(&p->status,
14500 "Non-base64 characters in bytes field: %s",
14501 upb_fielddef_name(p->top->f));
14502 upb_env_reporterror(p->env, &p->status);
14503 return false;
14504 } if (ptr[2] == '=') {
14505 uint32_t val;
14506 char output;
14507
14508 /* Last group contains only two input bytes, one output byte. */
14509 if (ptr[0] == '=' || ptr[1] == '=' || ptr[3] != '=') {
14510 goto badpadding;
14511 }
14512
14513 val = b64lookup(ptr[0]) << 18 |
14514 b64lookup(ptr[1]) << 12;
14515
14516 UPB_ASSERT(!(val & 0x80000000));
14517 output = val >> 16;
14518 upb_sink_putstring(&p->top->sink, sel, &output, 1, NULL);
14519 return true;
14520 } else {
14521 uint32_t val;
14522 char output[2];
14523
14524 /* Last group contains only three input bytes, two output bytes. */
14525 if (ptr[0] == '=' || ptr[1] == '=' || ptr[2] == '=') {
14526 goto badpadding;
14527 }
14528
14529 val = b64lookup(ptr[0]) << 18 |
14530 b64lookup(ptr[1]) << 12 |
14531 b64lookup(ptr[2]) << 6;
14532
14533 output[0] = val >> 16;
14534 output[1] = (val >> 8) & 0xff;
14535 upb_sink_putstring(&p->top->sink, sel, output, 2, NULL);
14536 return true;
14537 }
14538
14539badpadding:
14540 upb_status_seterrf(&p->status,
14541 "Incorrect base64 padding for field: %s (%.*s)",
14542 upb_fielddef_name(p->top->f),
14543 4, ptr);
14544 upb_env_reporterror(p->env, &p->status);
14545 return false;
14546}
14547
14548
14549/* Accumulate buffer **********************************************************/
14550
14551/* Functionality for accumulating a buffer.
14552 *
14553 * Some parts of the parser need an entire value as a contiguous string. For
14554 * example, to look up a member name in a hash table, or to turn a string into
14555 * a number, the relevant library routines need the input string to be in
14556 * contiguous memory, even if the value spanned two or more buffers in the
14557 * input. These routines handle that.
14558 *
14559 * In the common case we can just point to the input buffer to get this
14560 * contiguous string and avoid any actual copy. So we optimistically begin
14561 * this way. But there are a few cases where we must instead copy into a
14562 * separate buffer:
14563 *
14564 * 1. The string was not contiguous in the input (it spanned buffers).
14565 *
14566 * 2. The string included escape sequences that need to be interpreted to get
14567 * the true value in a contiguous buffer. */
14568
14569static void assert_accumulate_empty(upb_json_parser *p) {
14570 UPB_ASSERT(p->accumulated == NULL);
14571 UPB_ASSERT(p->accumulated_len == 0);
14572}
14573
14574static void accumulate_clear(upb_json_parser *p) {
14575 p->accumulated = NULL;
14576 p->accumulated_len = 0;
14577}
14578
14579/* Used internally by accumulate_append(). */
14580static bool accumulate_realloc(upb_json_parser *p, size_t need) {
14581 void *mem;
14582 size_t old_size = p->accumulate_buf_size;
14583 size_t new_size = UPB_MAX(old_size, 128);
14584 while (new_size < need) {
14585 new_size = saturating_multiply(new_size, 2);
14586 }
14587
14588 mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size);
14589 if (!mem) {
14590 upb_status_seterrmsg(&p->status, "Out of memory allocating buffer.");
14591 upb_env_reporterror(p->env, &p->status);
14592 return false;
14593 }
14594
14595 p->accumulate_buf = mem;
14596 p->accumulate_buf_size = new_size;
14597 return true;
14598}
14599
14600/* Logically appends the given data to the append buffer.
14601 * If "can_alias" is true, we will try to avoid actually copying, but the buffer
14602 * must be valid until the next accumulate_append() call (if any). */
14603static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
14604 bool can_alias) {
14605 size_t need;
14606
14607 if (!p->accumulated && can_alias) {
14608 p->accumulated = buf;
14609 p->accumulated_len = len;
14610 return true;
14611 }
14612
14613 if (!checked_add(p->accumulated_len, len, &need)) {
14614 upb_status_seterrmsg(&p->status, "Integer overflow.");
14615 upb_env_reporterror(p->env, &p->status);
14616 return false;
14617 }
14618
14619 if (need > p->accumulate_buf_size && !accumulate_realloc(p, need)) {
14620 return false;
14621 }
14622
14623 if (p->accumulated != p->accumulate_buf) {
14624 memcpy(p->accumulate_buf, p->accumulated, p->accumulated_len);
14625 p->accumulated = p->accumulate_buf;
14626 }
14627
14628 memcpy(p->accumulate_buf + p->accumulated_len, buf, len);
14629 p->accumulated_len += len;
14630 return true;
14631}
14632
14633/* Returns a pointer to the data accumulated since the last accumulate_clear()
14634 * call, and writes the length to *len. This with point either to the input
14635 * buffer or a temporary accumulate buffer. */
14636static const char *accumulate_getptr(upb_json_parser *p, size_t *len) {
14637 UPB_ASSERT(p->accumulated);
14638 *len = p->accumulated_len;
14639 return p->accumulated;
14640}
14641
14642
14643/* Mult-part text data ********************************************************/
14644
14645/* When we have text data in the input, it can often come in multiple segments.
14646 * For example, there may be some raw string data followed by an escape
14647 * sequence. The two segments are processed with different logic. Also buffer
14648 * seams in the input can cause multiple segments.
14649 *
14650 * As we see segments, there are two main cases for how we want to process them:
14651 *
14652 * 1. we want to push the captured input directly to string handlers.
14653 *
14654 * 2. we need to accumulate all the parts into a contiguous buffer for further
14655 * processing (field name lookup, string->number conversion, etc). */
14656
14657/* This is the set of states for p->multipart_state. */
14658enum {
14659 /* We are not currently processing multipart data. */
14660 MULTIPART_INACTIVE = 0,
14661
14662 /* We are processing multipart data by accumulating it into a contiguous
14663 * buffer. */
14664 MULTIPART_ACCUMULATE = 1,
14665
14666 /* We are processing multipart data by pushing each part directly to the
14667 * current string handlers. */
14668 MULTIPART_PUSHEAGERLY = 2
14669};
14670
14671/* Start a multi-part text value where we accumulate the data for processing at
14672 * the end. */
14673static void multipart_startaccum(upb_json_parser *p) {
14674 assert_accumulate_empty(p);
14675 UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
14676 p->multipart_state = MULTIPART_ACCUMULATE;
14677}
14678
14679/* Start a multi-part text value where we immediately push text data to a string
14680 * value with the given selector. */
14681static void multipart_start(upb_json_parser *p, upb_selector_t sel) {
14682 assert_accumulate_empty(p);
14683 UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
14684 p->multipart_state = MULTIPART_PUSHEAGERLY;
14685 p->string_selector = sel;
14686}
14687
14688static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
14689 bool can_alias) {
14690 switch (p->multipart_state) {
14691 case MULTIPART_INACTIVE:
14692 upb_status_seterrmsg(
14693 &p->status, "Internal error: unexpected state MULTIPART_INACTIVE");
14694 upb_env_reporterror(p->env, &p->status);
14695 return false;
14696
14697 case MULTIPART_ACCUMULATE:
14698 if (!accumulate_append(p, buf, len, can_alias)) {
14699 return false;
14700 }
14701 break;
14702
14703 case MULTIPART_PUSHEAGERLY: {
14704 const upb_bufhandle *handle = can_alias ? p->handle : NULL;
14705 upb_sink_putstring(&p->top->sink, p->string_selector, buf, len, handle);
14706 break;
14707 }
14708 }
14709
14710 return true;
14711}
14712
14713/* Note: this invalidates the accumulate buffer! Call only after reading its
14714 * contents. */
14715static void multipart_end(upb_json_parser *p) {
14716 UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
14717 p->multipart_state = MULTIPART_INACTIVE;
14718 accumulate_clear(p);
14719}
14720
14721
14722/* Input capture **************************************************************/
14723
14724/* Functionality for capturing a region of the input as text. Gracefully
14725 * handles the case where a buffer seam occurs in the middle of the captured
14726 * region. */
14727
14728static void capture_begin(upb_json_parser *p, const char *ptr) {
14729 UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
14730 UPB_ASSERT(p->capture == NULL);
14731 p->capture = ptr;
14732}
14733
14734static bool capture_end(upb_json_parser *p, const char *ptr) {
14735 UPB_ASSERT(p->capture);
14736 if (multipart_text(p, p->capture, ptr - p->capture, true)) {
14737 p->capture = NULL;
14738 return true;
14739 } else {
14740 return false;
14741 }
14742}
14743
14744/* This is called at the end of each input buffer (ie. when we have hit a
14745 * buffer seam). If we are in the middle of capturing the input, this
14746 * processes the unprocessed capture region. */
14747static void capture_suspend(upb_json_parser *p, const char **ptr) {
14748 if (!p->capture) return;
14749
14750 if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
14751 /* We use this as a signal that we were in the middle of capturing, and
14752 * that capturing should resume at the beginning of the next buffer.
14753 *
14754 * We can't use *ptr here, because we have no guarantee that this pointer
14755 * will be valid when we resume (if the underlying memory is freed, then
14756 * using the pointer at all, even to compare to NULL, is likely undefined
14757 * behavior). */
14758 p->capture = &suspend_capture;
14759 } else {
14760 /* Need to back up the pointer to the beginning of the capture, since
14761 * we were not able to actually preserve it. */
14762 *ptr = p->capture;
14763 }
14764}
14765
14766static void capture_resume(upb_json_parser *p, const char *ptr) {
14767 if (p->capture) {
14768 UPB_ASSERT(p->capture == &suspend_capture);
14769 p->capture = ptr;
14770 }
14771}
14772
14773
14774/* Callbacks from the parser **************************************************/
14775
14776/* These are the functions called directly from the parser itself.
14777 * We define these in the same order as their declarations in the parser. */
14778
14779static char escape_char(char in) {
14780 switch (in) {
14781 case 'r': return '\r';
14782 case 't': return '\t';
14783 case 'n': return '\n';
14784 case 'f': return '\f';
14785 case 'b': return '\b';
14786 case '/': return '/';
14787 case '"': return '"';
14788 case '\\': return '\\';
14789 default:
14790 UPB_ASSERT(0);
14791 return 'x';
14792 }
14793}
14794
14795static bool escape(upb_json_parser *p, const char *ptr) {
14796 char ch = escape_char(*ptr);
14797 return multipart_text(p, &ch, 1, false);
14798}
14799
14800static void start_hex(upb_json_parser *p) {
14801 p->digit = 0;
14802}
14803
14804static void hexdigit(upb_json_parser *p, const char *ptr) {
14805 char ch = *ptr;
14806
14807 p->digit <<= 4;
14808
14809 if (ch >= '0' && ch <= '9') {
14810 p->digit += (ch - '0');
14811 } else if (ch >= 'a' && ch <= 'f') {
14812 p->digit += ((ch - 'a') + 10);
14813 } else {
14814 UPB_ASSERT(ch >= 'A' && ch <= 'F');
14815 p->digit += ((ch - 'A') + 10);
14816 }
14817}
14818
14819static bool end_hex(upb_json_parser *p) {
14820 uint32_t codepoint = p->digit;
14821
14822 /* emit the codepoint as UTF-8. */
14823 char utf8[3]; /* support \u0000 -- \uFFFF -- need only three bytes. */
14824 int length = 0;
14825 if (codepoint <= 0x7F) {
14826 utf8[0] = codepoint;
14827 length = 1;
14828 } else if (codepoint <= 0x07FF) {
14829 utf8[1] = (codepoint & 0x3F) | 0x80;
14830 codepoint >>= 6;
14831 utf8[0] = (codepoint & 0x1F) | 0xC0;
14832 length = 2;
14833 } else /* codepoint <= 0xFFFF */ {
14834 utf8[2] = (codepoint & 0x3F) | 0x80;
14835 codepoint >>= 6;
14836 utf8[1] = (codepoint & 0x3F) | 0x80;
14837 codepoint >>= 6;
14838 utf8[0] = (codepoint & 0x0F) | 0xE0;
14839 length = 3;
14840 }
14841 /* TODO(haberman): Handle high surrogates: if codepoint is a high surrogate
14842 * we have to wait for the next escape to get the full code point). */
14843
14844 return multipart_text(p, utf8, length, false);
14845}
14846
14847static void start_text(upb_json_parser *p, const char *ptr) {
14848 capture_begin(p, ptr);
14849}
14850
14851static bool end_text(upb_json_parser *p, const char *ptr) {
14852 return capture_end(p, ptr);
14853}
14854
14855static void start_number(upb_json_parser *p, const char *ptr) {
14856 multipart_startaccum(p);
14857 capture_begin(p, ptr);
14858}
14859
14860static bool parse_number(upb_json_parser *p, bool is_quoted);
14861
14862static bool end_number(upb_json_parser *p, const char *ptr) {
14863 if (!capture_end(p, ptr)) {
14864 return false;
14865 }
14866
14867 return parse_number(p, false);
14868}
14869
14870/* |buf| is NULL-terminated. |buf| itself will never include quotes;
14871 * |is_quoted| tells us whether this text originally appeared inside quotes. */
14872static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
14873 bool is_quoted) {
14874 size_t len = strlen(buf);
14875 const char *bufend = buf + len;
14876 char *end;
14877 upb_fieldtype_t type = upb_fielddef_type(p->top->f);
14878 double val;
14879 double dummy;
14880 double inf = 1.0 / 0.0; /* C89 does not have an INFINITY macro. */
14881
14882 errno = 0;
14883
14884 if (len == 0 || buf[0] == ' ') {
14885 return false;
14886 }
14887
14888 /* For integer types, first try parsing with integer-specific routines.
14889 * If these succeed, they will be more accurate for int64/uint64 than
14890 * strtod().
14891 */
14892 switch (type) {
14893 case UPB_TYPE_ENUM:
14894 case UPB_TYPE_INT32: {
14895 long val = strtol(buf, &end, 0);
14896 if (errno == ERANGE || end != bufend) {
14897 break;
14898 } else if (val > INT32_MAX || val < INT32_MIN) {
14899 return false;
14900 } else {
14901 upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
14902 return true;
14903 }
14904 }
14905 case UPB_TYPE_UINT32: {
14906 unsigned long val = strtoul(buf, &end, 0);
14907 if (end != bufend) {
14908 break;
14909 } else if (val > UINT32_MAX || errno == ERANGE) {
14910 return false;
14911 } else {
14912 upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
14913 return true;
14914 }
14915 }
14916 /* XXX: We can't handle [u]int64 properly on 32-bit machines because
14917 * strto[u]ll isn't in C89. */
14918 case UPB_TYPE_INT64: {
14919 long val = strtol(buf, &end, 0);
14920 if (errno == ERANGE || end != bufend) {
14921 break;
14922 } else {
14923 upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
14924 return true;
14925 }
14926 }
14927 case UPB_TYPE_UINT64: {
14928 unsigned long val = strtoul(p->accumulated, &end, 0);
14929 if (end != bufend) {
14930 break;
14931 } else if (errno == ERANGE) {
14932 return false;
14933 } else {
14934 upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
14935 return true;
14936 }
14937 }
14938 default:
14939 break;
14940 }
14941
14942 if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
14943 /* Quoted numbers for integer types are not allowed to be in double form. */
14944 return false;
14945 }
14946
14947 if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
14948 /* C89 does not have an INFINITY macro. */
14949 val = inf;
14950 } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
14951 val = -inf;
14952 } else {
14953 val = strtod(buf, &end);
14954 if (errno == ERANGE || end != bufend) {
14955 return false;
14956 }
14957 }
14958
14959 switch (type) {
14960#define CASE(capitaltype, smalltype, ctype, min, max) \
14961 case UPB_TYPE_ ## capitaltype: { \
14962 if (modf(val, &dummy) != 0 || val > max || val < min) { \
14963 return false; \
14964 } else { \
14965 upb_sink_put ## smalltype(&p->top->sink, parser_getsel(p), \
14966 (ctype)val); \
14967 return true; \
14968 } \
14969 break; \
14970 }
14971 case UPB_TYPE_ENUM:
14972 CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
14973 CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
14974 CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
14975 CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
14976#undef CASE
14977
14978 case UPB_TYPE_DOUBLE:
14979 upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
14980 return true;
14981 case UPB_TYPE_FLOAT:
14982 if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
14983 return false;
14984 } else {
14985 upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
14986 return true;
14987 }
14988 default:
14989 return false;
14990 }
14991}
14992
14993static bool parse_number(upb_json_parser *p, bool is_quoted) {
14994 size_t len;
14995 const char *buf;
14996
14997 /* strtol() and friends unfortunately do not support specifying the length of
14998 * the input string, so we need to force a copy into a NULL-terminated buffer. */
14999 if (!multipart_text(p, "\0", 1, false)) {
15000 return false;
15001 }
15002
15003 buf = accumulate_getptr(p, &len);
15004
15005 if (parse_number_from_buffer(p, buf, is_quoted)) {
15006 multipart_end(p);
15007 return true;
15008 } else {
15009 upb_status_seterrf(&p->status, "error parsing number: %s", buf);
15010 upb_env_reporterror(p->env, &p->status);
15011 multipart_end(p);
15012 return false;
15013 }
15014}
15015
15016static bool parser_putbool(upb_json_parser *p, bool val) {
15017 bool ok;
15018
15019 if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
15020 upb_status_seterrf(&p->status,
15021 "Boolean value specified for non-bool field: %s",
15022 upb_fielddef_name(p->top->f));
15023 upb_env_reporterror(p->env, &p->status);
15024 return false;
15025 }
15026
15027 ok = upb_sink_putbool(&p->top->sink, parser_getsel(p), val);
15028 UPB_ASSERT(ok);
15029
15030 return true;
15031}
15032
15033static bool start_stringval(upb_json_parser *p) {
15034 UPB_ASSERT(p->top->f);
15035
15036 if (upb_fielddef_isstring(p->top->f)) {
15037 upb_jsonparser_frame *inner;
15038 upb_selector_t sel;
15039
15040 if (!check_stack(p)) return false;
15041
15042 /* Start a new parser frame: parser frames correspond one-to-one with
15043 * handler frames, and string events occur in a sub-frame. */
15044 inner = p->top + 1;
15045 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
15046 upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
15047 inner->m = p->top->m;
15048 inner->f = p->top->f;
15049 inner->name_table = NULL;
15050 inner->is_map = false;
15051 inner->is_mapentry = false;
15052 p->top = inner;
15053
15054 if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
15055 /* For STRING fields we push data directly to the handlers as it is
15056 * parsed. We don't do this yet for BYTES fields, because our base64
15057 * decoder is not streaming.
15058 *
15059 * TODO(haberman): make base64 decoding streaming also. */
15060 multipart_start(p, getsel_for_handlertype(p, UPB_HANDLER_STRING));
15061 return true;
15062 } else {
15063 multipart_startaccum(p);
15064 return true;
15065 }
15066 } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
15067 upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
15068 /* No need to push a frame -- numeric values in quotes remain in the
15069 * current parser frame. These values must accmulate so we can convert
15070 * them all at once at the end. */
15071 multipart_startaccum(p);
15072 return true;
15073 } else {
15074 upb_status_seterrf(&p->status,
15075 "String specified for bool or submessage field: %s",
15076 upb_fielddef_name(p->top->f));
15077 upb_env_reporterror(p->env, &p->status);
15078 return false;
15079 }
15080}
15081
15082static bool end_stringval(upb_json_parser *p) {
15083 bool ok = true;
15084
15085 switch (upb_fielddef_type(p->top->f)) {
15086 case UPB_TYPE_BYTES:
15087 if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
15088 p->accumulated, p->accumulated_len)) {
15089 return false;
15090 }
15091 /* Fall through. */
15092
15093 case UPB_TYPE_STRING: {
15094 upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
15095 p->top--;
15096 upb_sink_endstr(&p->top->sink, sel);
15097 break;
15098 }
15099
15100 case UPB_TYPE_ENUM: {
15101 /* Resolve enum symbolic name to integer value. */
15102 const upb_enumdef *enumdef =
15103 (const upb_enumdef*)upb_fielddef_subdef(p->top->f);
15104
15105 size_t len;
15106 const char *buf = accumulate_getptr(p, &len);
15107
15108 int32_t int_val = 0;
15109 ok = upb_enumdef_ntoi(enumdef, buf, len, &int_val);
15110
15111 if (ok) {
15112 upb_selector_t sel = parser_getsel(p);
15113 upb_sink_putint32(&p->top->sink, sel, int_val);
15114 } else {
15115 upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf);
15116 upb_env_reporterror(p->env, &p->status);
15117 }
15118
15119 break;
15120 }
15121
15122 case UPB_TYPE_INT32:
15123 case UPB_TYPE_INT64:
15124 case UPB_TYPE_UINT32:
15125 case UPB_TYPE_UINT64:
15126 case UPB_TYPE_DOUBLE:
15127 case UPB_TYPE_FLOAT:
15128 ok = parse_number(p, true);
15129 break;
15130
15131 default:
15132 UPB_ASSERT(false);
15133 upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
15134 upb_env_reporterror(p->env, &p->status);
15135 ok = false;
15136 break;
15137 }
15138
15139 multipart_end(p);
15140
15141 return ok;
15142}
15143
15144static void start_member(upb_json_parser *p) {
15145 UPB_ASSERT(!p->top->f);
15146 multipart_startaccum(p);
15147}
15148
15149/* Helper: invoked during parse_mapentry() to emit the mapentry message's key
15150 * field based on the current contents of the accumulate buffer. */
15151static bool parse_mapentry_key(upb_json_parser *p) {
15152
15153 size_t len;
15154 const char *buf = accumulate_getptr(p, &len);
15155
15156 /* Emit the key field. We do a bit of ad-hoc parsing here because the
15157 * parser state machine has already decided that this is a string field
15158 * name, and we are reinterpreting it as some arbitrary key type. In
15159 * particular, integer and bool keys are quoted, so we need to parse the
15160 * quoted string contents here. */
15161
15162 p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
15163 if (p->top->f == NULL) {
15164 upb_status_seterrmsg(&p->status, "mapentry message has no key");
15165 upb_env_reporterror(p->env, &p->status);
15166 return false;
15167 }
15168 switch (upb_fielddef_type(p->top->f)) {
15169 case UPB_TYPE_INT32:
15170 case UPB_TYPE_INT64:
15171 case UPB_TYPE_UINT32:
15172 case UPB_TYPE_UINT64:
15173 /* Invoke end_number. The accum buffer has the number's text already. */
15174 if (!parse_number(p, true)) {
15175 return false;
15176 }
15177 break;
15178 case UPB_TYPE_BOOL:
15179 if (len == 4 && !strncmp(buf, "true", 4)) {
15180 if (!parser_putbool(p, true)) {
15181 return false;
15182 }
15183 } else if (len == 5 && !strncmp(buf, "false", 5)) {
15184 if (!parser_putbool(p, false)) {
15185 return false;
15186 }
15187 } else {
15188 upb_status_seterrmsg(&p->status,
15189 "Map bool key not 'true' or 'false'");
15190 upb_env_reporterror(p->env, &p->status);
15191 return false;
15192 }
15193 multipart_end(p);
15194 break;
15195 case UPB_TYPE_STRING:
15196 case UPB_TYPE_BYTES: {
15197 upb_sink subsink;
15198 upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
15199 upb_sink_startstr(&p->top->sink, sel, len, &subsink);
15200 sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
15201 upb_sink_putstring(&subsink, sel, buf, len, NULL);
15202 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
15203 upb_sink_endstr(&p->top->sink, sel);
15204 multipart_end(p);
15205 break;
15206 }
15207 default:
15208 upb_status_seterrmsg(&p->status, "Invalid field type for map key");
15209 upb_env_reporterror(p->env, &p->status);
15210 return false;
15211 }
15212
15213 return true;
15214}
15215
15216/* Helper: emit one map entry (as a submessage in the map field sequence). This
15217 * is invoked from end_membername(), at the end of the map entry's key string,
15218 * with the map key in the accumulate buffer. It parses the key from that
15219 * buffer, emits the handler calls to start the mapentry submessage (setting up
15220 * its subframe in the process), and sets up state in the subframe so that the
15221 * value parser (invoked next) will emit the mapentry's value field and then
15222 * end the mapentry message. */
15223
15224static bool handle_mapentry(upb_json_parser *p) {
15225 const upb_fielddef *mapfield;
15226 const upb_msgdef *mapentrymsg;
15227 upb_jsonparser_frame *inner;
15228 upb_selector_t sel;
15229
15230 /* Map entry: p->top->sink is the seq frame, so we need to start a frame
15231 * for the mapentry itself, and then set |f| in that frame so that the map
15232 * value field is parsed, and also set a flag to end the frame after the
15233 * map-entry value is parsed. */
15234 if (!check_stack(p)) return false;
15235
15236 mapfield = p->top->mapfield;
15237 mapentrymsg = upb_fielddef_msgsubdef(mapfield);
15238
15239 inner = p->top + 1;
15240 p->top->f = mapfield;
15241 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
15242 upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
15243 inner->m = mapentrymsg;
15244 inner->name_table = NULL;
15245 inner->mapfield = mapfield;
15246 inner->is_map = false;
15247
15248 /* Don't set this to true *yet* -- we reuse parsing handlers below to push
15249 * the key field value to the sink, and these handlers will pop the frame
15250 * if they see is_mapentry (when invoked by the parser state machine, they
15251 * would have just seen the map-entry value, not key). */
15252 inner->is_mapentry = false;
15253 p->top = inner;
15254
15255 /* send STARTMSG in submsg frame. */
15256 upb_sink_startmsg(&p->top->sink);
15257
15258 parse_mapentry_key(p);
15259
15260 /* Set up the value field to receive the map-entry value. */
15261 p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
15262 p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */
15263 p->top->mapfield = mapfield;
15264 if (p->top->f == NULL) {
15265 upb_status_seterrmsg(&p->status, "mapentry message has no value");
15266 upb_env_reporterror(p->env, &p->status);
15267 return false;
15268 }
15269
15270 return true;
15271}
15272
15273static bool end_membername(upb_json_parser *p) {
15274 UPB_ASSERT(!p->top->f);
15275
15276 if (p->top->is_map) {
15277 return handle_mapentry(p);
15278 } else {
15279 size_t len;
15280 const char *buf = accumulate_getptr(p, &len);
15281 upb_value v;
15282
15283 if (upb_strtable_lookup2(p->top->name_table, buf, len, &v)) {
15284 p->top->f = upb_value_getconstptr(v);
15285 multipart_end(p);
15286
15287 return true;
15288 } else {
15289 /* TODO(haberman): Ignore unknown fields if requested/configured to do
15290 * so. */
15291 upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
15292 upb_env_reporterror(p->env, &p->status);
15293 return false;
15294 }
15295 }
15296}
15297
15298static void end_member(upb_json_parser *p) {
15299 /* If we just parsed a map-entry value, end that frame too. */
15300 if (p->top->is_mapentry) {
15301 upb_status s = UPB_STATUS_INIT;
15302 upb_selector_t sel;
15303 bool ok;
15304 const upb_fielddef *mapfield;
15305
15306 UPB_ASSERT(p->top > p->stack);
15307 /* send ENDMSG on submsg. */
15308 upb_sink_endmsg(&p->top->sink, &s);
15309 mapfield = p->top->mapfield;
15310
15311 /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
15312 p->top--;
15313 ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
15314 UPB_ASSERT(ok);
15315 upb_sink_endsubmsg(&p->top->sink, sel);
15316 }
15317
15318 p->top->f = NULL;
15319}
15320
15321static bool start_subobject(upb_json_parser *p) {
15322 UPB_ASSERT(p->top->f);
15323
15324 if (upb_fielddef_ismap(p->top->f)) {
15325 upb_jsonparser_frame *inner;
15326 upb_selector_t sel;
15327
15328 /* Beginning of a map. Start a new parser frame in a repeated-field
15329 * context. */
15330 if (!check_stack(p)) return false;
15331
15332 inner = p->top + 1;
15333 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
15334 upb_sink_startseq(&p->top->sink, sel, &inner->sink);
15335 inner->m = upb_fielddef_msgsubdef(p->top->f);
15336 inner->name_table = NULL;
15337 inner->mapfield = p->top->f;
15338 inner->f = NULL;
15339 inner->is_map = true;
15340 inner->is_mapentry = false;
15341 p->top = inner;
15342
15343 return true;
15344 } else if (upb_fielddef_issubmsg(p->top->f)) {
15345 upb_jsonparser_frame *inner;
15346 upb_selector_t sel;
15347
15348 /* Beginning of a subobject. Start a new parser frame in the submsg
15349 * context. */
15350 if (!check_stack(p)) return false;
15351
15352 inner = p->top + 1;
15353
15354 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
15355 upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
15356 inner->m = upb_fielddef_msgsubdef(p->top->f);
15357 set_name_table(p, inner);
15358 inner->f = NULL;
15359 inner->is_map = false;
15360 inner->is_mapentry = false;
15361 p->top = inner;
15362
15363 return true;
15364 } else {
15365 upb_status_seterrf(&p->status,
15366 "Object specified for non-message/group field: %s",
15367 upb_fielddef_name(p->top->f));
15368 upb_env_reporterror(p->env, &p->status);
15369 return false;
15370 }
15371}
15372
15373static void end_subobject(upb_json_parser *p) {
15374 if (p->top->is_map) {
15375 upb_selector_t sel;
15376 p->top--;
15377 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
15378 upb_sink_endseq(&p->top->sink, sel);
15379 } else {
15380 upb_selector_t sel;
15381 p->top--;
15382 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
15383 upb_sink_endsubmsg(&p->top->sink, sel);
15384 }
15385}
15386
15387static bool start_array(upb_json_parser *p) {
15388 upb_jsonparser_frame *inner;
15389 upb_selector_t sel;
15390
15391 UPB_ASSERT(p->top->f);
15392
15393 if (!upb_fielddef_isseq(p->top->f)) {
15394 upb_status_seterrf(&p->status,
15395 "Array specified for non-repeated field: %s",
15396 upb_fielddef_name(p->top->f));
15397 upb_env_reporterror(p->env, &p->status);
15398 return false;
15399 }
15400
15401 if (!check_stack(p)) return false;
15402
15403 inner = p->top + 1;
15404 sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
15405 upb_sink_startseq(&p->top->sink, sel, &inner->sink);
15406 inner->m = p->top->m;
15407 inner->name_table = NULL;
15408 inner->f = p->top->f;
15409 inner->is_map = false;
15410 inner->is_mapentry = false;
15411 p->top = inner;
15412
15413 return true;
15414}
15415
15416static void end_array(upb_json_parser *p) {
15417 upb_selector_t sel;
15418
15419 UPB_ASSERT(p->top > p->stack);
15420
15421 p->top--;
15422 sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
15423 upb_sink_endseq(&p->top->sink, sel);
15424}
15425
15426static void start_object(upb_json_parser *p) {
15427 if (!p->top->is_map) {
15428 upb_sink_startmsg(&p->top->sink);
15429 }
15430}
15431
15432static void end_object(upb_json_parser *p) {
15433 if (!p->top->is_map) {
15434 upb_status status;
15435 upb_status_clear(&status);
15436 upb_sink_endmsg(&p->top->sink, &status);
15437 if (!upb_ok(&status)) {
15438 upb_env_reporterror(p->env, &status);
15439 }
15440 }
15441}
15442
15443
15444#define CHECK_RETURN_TOP(x) if (!(x)) goto error
15445
15446
15447/* The actual parser **********************************************************/
15448
15449/* What follows is the Ragel parser itself. The language is specified in Ragel
15450 * and the actions call our C functions above.
15451 *
15452 * Ragel has an extensive set of functionality, and we use only a small part of
15453 * it. There are many action types but we only use a few:
15454 *
15455 * ">" -- transition into a machine
15456 * "%" -- transition out of a machine
15457 * "@" -- transition into a final state of a machine.
15458 *
15459 * "@" transitions are tricky because a machine can transition into a final
15460 * state repeatedly. But in some cases we know this can't happen, for example
15461 * a string which is delimited by a final '"' can only transition into its
15462 * final state once, when the closing '"' is seen. */
15463
15464
15465#line 1310 "upb/json/parser.rl"
15466
15467
15468
15469#line 1222 "upb/json/parser.c"
15470static const char _json_actions[] = {
15471 0, 1, 0, 1, 2, 1, 3, 1,
15472 5, 1, 6, 1, 7, 1, 8, 1,
15473 10, 1, 12, 1, 13, 1, 14, 1,
15474 15, 1, 16, 1, 17, 1, 21, 1,
15475 25, 1, 27, 2, 3, 8, 2, 4,
15476 5, 2, 6, 2, 2, 6, 8, 2,
15477 11, 9, 2, 13, 15, 2, 14, 15,
15478 2, 18, 1, 2, 19, 27, 2, 20,
15479 9, 2, 22, 27, 2, 23, 27, 2,
15480 24, 27, 2, 26, 27, 3, 14, 11,
15481 9
15482};
15483
15484static const unsigned char _json_key_offsets[] = {
15485 0, 0, 4, 9, 14, 15, 19, 24,
15486 29, 34, 38, 42, 45, 48, 50, 54,
15487 58, 60, 62, 67, 69, 71, 80, 86,
15488 92, 98, 104, 106, 115, 116, 116, 116,
15489 121, 126, 131, 132, 133, 134, 135, 135,
15490 136, 137, 138, 138, 139, 140, 141, 141,
15491 146, 151, 152, 156, 161, 166, 171, 175,
15492 175, 178, 178, 178
15493};
15494
15495static const char _json_trans_keys[] = {
15496 32, 123, 9, 13, 32, 34, 125, 9,
15497 13, 32, 34, 125, 9, 13, 34, 32,
15498 58, 9, 13, 32, 93, 125, 9, 13,
15499 32, 44, 125, 9, 13, 32, 44, 125,
15500 9, 13, 32, 34, 9, 13, 45, 48,
15501 49, 57, 48, 49, 57, 46, 69, 101,
15502 48, 57, 69, 101, 48, 57, 43, 45,
15503 48, 57, 48, 57, 48, 57, 46, 69,
15504 101, 48, 57, 34, 92, 34, 92, 34,
15505 47, 92, 98, 102, 110, 114, 116, 117,
15506 48, 57, 65, 70, 97, 102, 48, 57,
15507 65, 70, 97, 102, 48, 57, 65, 70,
15508 97, 102, 48, 57, 65, 70, 97, 102,
15509 34, 92, 34, 45, 91, 102, 110, 116,
15510 123, 48, 57, 34, 32, 93, 125, 9,
15511 13, 32, 44, 93, 9, 13, 32, 93,
15512 125, 9, 13, 97, 108, 115, 101, 117,
15513 108, 108, 114, 117, 101, 32, 34, 125,
15514 9, 13, 32, 34, 125, 9, 13, 34,
15515 32, 58, 9, 13, 32, 93, 125, 9,
15516 13, 32, 44, 125, 9, 13, 32, 44,
15517 125, 9, 13, 32, 34, 9, 13, 32,
15518 9, 13, 0
15519};
15520
15521static const char _json_single_lengths[] = {
15522 0, 2, 3, 3, 1, 2, 3, 3,
15523 3, 2, 2, 1, 3, 0, 2, 2,
15524 0, 0, 3, 2, 2, 9, 0, 0,
15525 0, 0, 2, 7, 1, 0, 0, 3,
15526 3, 3, 1, 1, 1, 1, 0, 1,
15527 1, 1, 0, 1, 1, 1, 0, 3,
15528 3, 1, 2, 3, 3, 3, 2, 0,
15529 1, 0, 0, 0
15530};
15531
15532static const char _json_range_lengths[] = {
15533 0, 1, 1, 1, 0, 1, 1, 1,
15534 1, 1, 1, 1, 0, 1, 1, 1,
15535 1, 1, 1, 0, 0, 0, 3, 3,
15536 3, 3, 0, 1, 0, 0, 0, 1,
15537 1, 1, 0, 0, 0, 0, 0, 0,
15538 0, 0, 0, 0, 0, 0, 0, 1,
15539 1, 0, 1, 1, 1, 1, 1, 0,
15540 1, 0, 0, 0
15541};
15542
15543static const short _json_index_offsets[] = {
15544 0, 0, 4, 9, 14, 16, 20, 25,
15545 30, 35, 39, 43, 46, 50, 52, 56,
15546 60, 62, 64, 69, 72, 75, 85, 89,
15547 93, 97, 101, 104, 113, 115, 116, 117,
15548 122, 127, 132, 134, 136, 138, 140, 141,
15549 143, 145, 147, 148, 150, 152, 154, 155,
15550 160, 165, 167, 171, 176, 181, 186, 190,
15551 191, 194, 195, 196
15552};
15553
15554static const char _json_indicies[] = {
15555 0, 2, 0, 1, 3, 4, 5, 3,
15556 1, 6, 7, 8, 6, 1, 9, 1,
15557 10, 11, 10, 1, 11, 1, 1, 11,
15558 12, 13, 14, 15, 13, 1, 16, 17,
15559 8, 16, 1, 17, 7, 17, 1, 18,
15560 19, 20, 1, 19, 20, 1, 22, 23,
15561 23, 21, 24, 1, 23, 23, 24, 21,
15562 25, 25, 26, 1, 26, 1, 26, 21,
15563 22, 23, 23, 20, 21, 28, 29, 27,
15564 31, 32, 30, 33, 33, 33, 33, 33,
15565 33, 33, 33, 34, 1, 35, 35, 35,
15566 1, 36, 36, 36, 1, 37, 37, 37,
15567 1, 38, 38, 38, 1, 40, 41, 39,
15568 42, 43, 44, 45, 46, 47, 48, 43,
15569 1, 49, 1, 50, 51, 53, 54, 1,
15570 53, 52, 55, 56, 54, 55, 1, 56,
15571 1, 1, 56, 52, 57, 1, 58, 1,
15572 59, 1, 60, 1, 61, 62, 1, 63,
15573 1, 64, 1, 65, 66, 1, 67, 1,
15574 68, 1, 69, 70, 71, 72, 70, 1,
15575 73, 74, 75, 73, 1, 76, 1, 77,
15576 78, 77, 1, 78, 1, 1, 78, 79,
15577 80, 81, 82, 80, 1, 83, 84, 75,
15578 83, 1, 84, 74, 84, 1, 85, 86,
15579 86, 1, 1, 1, 1, 0
15580};
15581
15582static const char _json_trans_targs[] = {
15583 1, 0, 2, 3, 4, 56, 3, 4,
15584 56, 5, 5, 6, 7, 8, 9, 56,
15585 8, 9, 11, 12, 18, 57, 13, 15,
15586 14, 16, 17, 20, 58, 21, 20, 58,
15587 21, 19, 22, 23, 24, 25, 26, 20,
15588 58, 21, 28, 30, 31, 34, 39, 43,
15589 47, 29, 59, 59, 32, 31, 29, 32,
15590 33, 35, 36, 37, 38, 59, 40, 41,
15591 42, 59, 44, 45, 46, 59, 48, 49,
15592 55, 48, 49, 55, 50, 50, 51, 52,
15593 53, 54, 55, 53, 54, 59, 56
15594};
15595
15596static const char _json_trans_actions[] = {
15597 0, 0, 0, 21, 77, 53, 0, 47,
15598 23, 17, 0, 0, 15, 19, 19, 50,
15599 0, 0, 0, 0, 0, 1, 0, 0,
15600 0, 0, 0, 3, 13, 0, 0, 35,
15601 5, 11, 0, 38, 7, 7, 7, 41,
15602 44, 9, 62, 56, 25, 0, 0, 0,
15603 31, 29, 33, 59, 15, 0, 27, 0,
15604 0, 0, 0, 0, 0, 68, 0, 0,
15605 0, 71, 0, 0, 0, 65, 21, 77,
15606 53, 0, 47, 23, 17, 0, 0, 15,
15607 19, 19, 50, 0, 0, 74, 0
15608};
15609
15610static const int json_start = 1;
15611
15612static const int json_en_number_machine = 10;
15613static const int json_en_string_machine = 19;
15614static const int json_en_value_machine = 27;
15615static const int json_en_main = 1;
15616
15617
15618#line 1313 "upb/json/parser.rl"
15619
15620size_t parse(void *closure, const void *hd, const char *buf, size_t size,
15621 const upb_bufhandle *handle) {
15622 upb_json_parser *parser = closure;
15623
15624 /* Variables used by Ragel's generated code. */
15625 int cs = parser->current_state;
15626 int *stack = parser->parser_stack;
15627 int top = parser->parser_top;
15628
15629 const char *p = buf;
15630 const char *pe = buf + size;
15631
15632 parser->handle = handle;
15633
15634 UPB_UNUSED(hd);
15635 UPB_UNUSED(handle);
15636
15637 capture_resume(parser, buf);
15638
15639
15640#line 1393 "upb/json/parser.c"
15641 {
15642 int _klen;
15643 unsigned int _trans;
15644 const char *_acts;
15645 unsigned int _nacts;
15646 const char *_keys;
15647
15648 if ( p == pe )
15649 goto _test_eof;
15650 if ( cs == 0 )
15651 goto _out;
15652_resume:
15653 _keys = _json_trans_keys + _json_key_offsets[cs];
15654 _trans = _json_index_offsets[cs];
15655
15656 _klen = _json_single_lengths[cs];
15657 if ( _klen > 0 ) {
15658 const char *_lower = _keys;
15659 const char *_mid;
15660 const char *_upper = _keys + _klen - 1;
15661 while (1) {
15662 if ( _upper < _lower )
15663 break;
15664
15665 _mid = _lower + ((_upper-_lower) >> 1);
15666 if ( (*p) < *_mid )
15667 _upper = _mid - 1;
15668 else if ( (*p) > *_mid )
15669 _lower = _mid + 1;
15670 else {
15671 _trans += (unsigned int)(_mid - _keys);
15672 goto _match;
15673 }
15674 }
15675 _keys += _klen;
15676 _trans += _klen;
15677 }
15678
15679 _klen = _json_range_lengths[cs];
15680 if ( _klen > 0 ) {
15681 const char *_lower = _keys;
15682 const char *_mid;
15683 const char *_upper = _keys + (_klen<<1) - 2;
15684 while (1) {
15685 if ( _upper < _lower )
15686 break;
15687
15688 _mid = _lower + (((_upper-_lower) >> 1) & ~1);
15689 if ( (*p) < _mid[0] )
15690 _upper = _mid - 2;
15691 else if ( (*p) > _mid[1] )
15692 _lower = _mid + 2;
15693 else {
15694 _trans += (unsigned int)((_mid - _keys)>>1);
15695 goto _match;
15696 }
15697 }
15698 _trans += _klen;
15699 }
15700
15701_match:
15702 _trans = _json_indicies[_trans];
15703 cs = _json_trans_targs[_trans];
15704
15705 if ( _json_trans_actions[_trans] == 0 )
15706 goto _again;
15707
15708 _acts = _json_actions + _json_trans_actions[_trans];
15709 _nacts = (unsigned int) *_acts++;
15710 while ( _nacts-- > 0 )
15711 {
15712 switch ( *_acts++ )
15713 {
15714 case 0:
15715#line 1225 "upb/json/parser.rl"
15716 { p--; {cs = stack[--top]; goto _again;} }
15717 break;
15718 case 1:
15719#line 1226 "upb/json/parser.rl"
15720 { p--; {stack[top++] = cs; cs = 10; goto _again;} }
15721 break;
15722 case 2:
15723#line 1230 "upb/json/parser.rl"
15724 { start_text(parser, p); }
15725 break;
15726 case 3:
15727#line 1231 "upb/json/parser.rl"
15728 { CHECK_RETURN_TOP(end_text(parser, p)); }
15729 break;
15730 case 4:
15731#line 1237 "upb/json/parser.rl"
15732 { start_hex(parser); }
15733 break;
15734 case 5:
15735#line 1238 "upb/json/parser.rl"
15736 { hexdigit(parser, p); }
15737 break;
15738 case 6:
15739#line 1239 "upb/json/parser.rl"
15740 { CHECK_RETURN_TOP(end_hex(parser)); }
15741 break;
15742 case 7:
15743#line 1245 "upb/json/parser.rl"
15744 { CHECK_RETURN_TOP(escape(parser, p)); }
15745 break;
15746 case 8:
15747#line 1251 "upb/json/parser.rl"
15748 { p--; {cs = stack[--top]; goto _again;} }
15749 break;
15750 case 9:
15751#line 1254 "upb/json/parser.rl"
15752 { {stack[top++] = cs; cs = 19; goto _again;} }
15753 break;
15754 case 10:
15755#line 1256 "upb/json/parser.rl"
15756 { p--; {stack[top++] = cs; cs = 27; goto _again;} }
15757 break;
15758 case 11:
15759#line 1261 "upb/json/parser.rl"
15760 { start_member(parser); }
15761 break;
15762 case 12:
15763#line 1262 "upb/json/parser.rl"
15764 { CHECK_RETURN_TOP(end_membername(parser)); }
15765 break;
15766 case 13:
15767#line 1265 "upb/json/parser.rl"
15768 { end_member(parser); }
15769 break;
15770 case 14:
15771#line 1271 "upb/json/parser.rl"
15772 { start_object(parser); }
15773 break;
15774 case 15:
15775#line 1274 "upb/json/parser.rl"
15776 { end_object(parser); }
15777 break;
15778 case 16:
15779#line 1280 "upb/json/parser.rl"
15780 { CHECK_RETURN_TOP(start_array(parser)); }
15781 break;
15782 case 17:
15783#line 1284 "upb/json/parser.rl"
15784 { end_array(parser); }
15785 break;
15786 case 18:
15787#line 1289 "upb/json/parser.rl"
15788 { start_number(parser, p); }
15789 break;
15790 case 19:
15791#line 1290 "upb/json/parser.rl"
15792 { CHECK_RETURN_TOP(end_number(parser, p)); }
15793 break;
15794 case 20:
15795#line 1292 "upb/json/parser.rl"
15796 { CHECK_RETURN_TOP(start_stringval(parser)); }
15797 break;
15798 case 21:
15799#line 1293 "upb/json/parser.rl"
15800 { CHECK_RETURN_TOP(end_stringval(parser)); }
15801 break;
15802 case 22:
15803#line 1295 "upb/json/parser.rl"
15804 { CHECK_RETURN_TOP(parser_putbool(parser, true)); }
15805 break;
15806 case 23:
15807#line 1297 "upb/json/parser.rl"
15808 { CHECK_RETURN_TOP(parser_putbool(parser, false)); }
15809 break;
15810 case 24:
15811#line 1299 "upb/json/parser.rl"
15812 { /* null value */ }
15813 break;
15814 case 25:
15815#line 1301 "upb/json/parser.rl"
15816 { CHECK_RETURN_TOP(start_subobject(parser)); }
15817 break;
15818 case 26:
15819#line 1302 "upb/json/parser.rl"
15820 { end_subobject(parser); }
15821 break;
15822 case 27:
15823#line 1307 "upb/json/parser.rl"
15824 { p--; {cs = stack[--top]; goto _again;} }
15825 break;
15826#line 1579 "upb/json/parser.c"
15827 }
15828 }
15829
15830_again:
15831 if ( cs == 0 )
15832 goto _out;
15833 if ( ++p != pe )
15834 goto _resume;
15835 _test_eof: {}
15836 _out: {}
15837 }
15838
15839#line 1334 "upb/json/parser.rl"
15840
15841 if (p != pe) {
15842 upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
15843 upb_env_reporterror(parser->env, &parser->status);
15844 } else {
15845 capture_suspend(parser, &p);
15846 }
15847
15848error:
15849 /* Save parsing state back to parser. */
15850 parser->current_state = cs;
15851 parser->parser_top = top;
15852
15853 return p - buf;
15854}
15855
15856bool end(void *closure, const void *hd) {
15857 UPB_UNUSED(closure);
15858 UPB_UNUSED(hd);
15859
15860 /* Prevent compile warning on unused static constants. */
15861 UPB_UNUSED(json_start);
15862 UPB_UNUSED(json_en_number_machine);
15863 UPB_UNUSED(json_en_string_machine);
15864 UPB_UNUSED(json_en_value_machine);
15865 UPB_UNUSED(json_en_main);
15866 return true;
15867}
15868
15869static void json_parser_reset(upb_json_parser *p) {
15870 int cs;
15871 int top;
15872
15873 p->top = p->stack;
15874 p->top->f = NULL;
15875 p->top->is_map = false;
15876 p->top->is_mapentry = false;
15877
15878 /* Emit Ragel initialization of the parser. */
15879
15880#line 1633 "upb/json/parser.c"
15881 {
15882 cs = json_start;
15883 top = 0;
15884 }
15885
15886#line 1374 "upb/json/parser.rl"
15887 p->current_state = cs;
15888 p->parser_top = top;
15889 accumulate_clear(p);
15890 p->multipart_state = MULTIPART_INACTIVE;
15891 p->capture = NULL;
15892 p->accumulated = NULL;
15893 upb_status_clear(&p->status);
15894}
15895
15896static void visit_json_parsermethod(const upb_refcounted *r,
15897 upb_refcounted_visit *visit,
15898 void *closure) {
15899 const upb_json_parsermethod *method = (upb_json_parsermethod*)r;
15900 visit(r, upb_msgdef_upcast2(method->msg), closure);
15901}
15902
15903static void free_json_parsermethod(upb_refcounted *r) {
15904 upb_json_parsermethod *method = (upb_json_parsermethod*)r;
15905
15906 upb_inttable_iter i;
15907 upb_inttable_begin(&i, &method->name_tables);
15908 for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
15909 upb_value val = upb_inttable_iter_value(&i);
15910 upb_strtable *t = upb_value_getptr(val);
15911 upb_strtable_uninit(t);
15912 upb_gfree(t);
15913 }
15914
15915 upb_inttable_uninit(&method->name_tables);
15916
15917 upb_gfree(r);
15918}
15919
15920static void add_jsonname_table(upb_json_parsermethod *m, const upb_msgdef* md) {
15921 upb_msg_field_iter i;
15922 upb_strtable *t;
15923
15924 /* It would be nice to stack-allocate this, but protobufs do not limit the
15925 * length of fields to any reasonable limit. */
15926 char *buf = NULL;
15927 size_t len = 0;
15928
15929 if (upb_inttable_lookupptr(&m->name_tables, md, NULL)) {
15930 return;
15931 }
15932
15933 /* TODO(haberman): handle malloc failure. */
15934 t = upb_gmalloc(sizeof(*t));
15935 upb_strtable_init(t, UPB_CTYPE_CONSTPTR);
15936 upb_inttable_insertptr(&m->name_tables, md, upb_value_ptr(t));
15937
15938 for(upb_msg_field_begin(&i, md);
15939 !upb_msg_field_done(&i);
15940 upb_msg_field_next(&i)) {
15941 const upb_fielddef *f = upb_msg_iter_field(&i);
15942
15943 /* Add an entry for the JSON name. */
15944 size_t field_len = upb_fielddef_getjsonname(f, buf, len);
15945 if (field_len > len) {
15946 size_t len2;
15947 buf = upb_grealloc(buf, 0, field_len);
15948 len = field_len;
15949 len2 = upb_fielddef_getjsonname(f, buf, len);
15950 UPB_ASSERT(len == len2);
15951 }
15952 upb_strtable_insert(t, buf, upb_value_constptr(f));
15953
15954 if (strcmp(buf, upb_fielddef_name(f)) != 0) {
15955 /* Since the JSON name is different from the regular field name, add an
15956 * entry for the raw name (compliant proto3 JSON parsers must accept
15957 * both). */
15958 upb_strtable_insert(t, upb_fielddef_name(f), upb_value_constptr(f));
15959 }
15960
15961 if (upb_fielddef_issubmsg(f)) {
15962 add_jsonname_table(m, upb_fielddef_msgsubdef(f));
15963 }
15964 }
15965
15966 upb_gfree(buf);
15967}
15968
15969/* Public API *****************************************************************/
15970
15971upb_json_parser *upb_json_parser_create(upb_env *env,
15972 const upb_json_parsermethod *method,
15973 upb_sink *output) {
15974#ifndef NDEBUG
15975 const size_t size_before = upb_env_bytesallocated(env);
15976#endif
15977 upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser));
15978 if (!p) return false;
15979
15980 p->env = env;
15981 p->method = method;
15982 p->limit = p->stack + UPB_JSON_MAX_DEPTH;
15983 p->accumulate_buf = NULL;
15984 p->accumulate_buf_size = 0;
15985 upb_bytessink_reset(&p->input_, &method->input_handler_, p);
15986
15987 json_parser_reset(p);
15988 upb_sink_reset(&p->top->sink, output->handlers, output->closure);
15989 p->top->m = upb_handlers_msgdef(output->handlers);
15990 set_name_table(p, p->top);
15991
15992 /* If this fails, uncomment and increase the value in parser.h. */
15993 /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
15994 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <=
15995 UPB_JSON_PARSER_SIZE);
15996 return p;
15997}
15998
15999upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
16000 return &p->input_;
16001}
16002
16003upb_json_parsermethod *upb_json_parsermethod_new(const upb_msgdef* md,
16004 const void* owner) {
16005 static const struct upb_refcounted_vtbl vtbl = {visit_json_parsermethod,
16006 free_json_parsermethod};
16007 upb_json_parsermethod *ret = upb_gmalloc(sizeof(*ret));
16008 upb_refcounted_init(upb_json_parsermethod_upcast_mutable(ret), &vtbl, owner);
16009
16010 ret->msg = md;
16011 upb_ref2(md, ret);
16012
16013 upb_byteshandler_init(&ret->input_handler_);
16014 upb_byteshandler_setstring(&ret->input_handler_, parse, ret);
16015 upb_byteshandler_setendstr(&ret->input_handler_, end, ret);
16016
16017 upb_inttable_init(&ret->name_tables, UPB_CTYPE_PTR);
16018
16019 add_jsonname_table(ret, md);
16020
16021 return ret;
16022}
16023
16024const upb_byteshandler *upb_json_parsermethod_inputhandler(
16025 const upb_json_parsermethod *m) {
16026 return &m->input_handler_;
16027}
16028/*
16029** This currently uses snprintf() to format primitives, and could be optimized
16030** further.
16031*/
16032
16033
16034#include <string.h>
16035#include <stdint.h>
16036
16037struct upb_json_printer {
16038 upb_sink input_;
16039 /* BytesSink closure. */
16040 void *subc_;
16041 upb_bytessink *output_;
16042
16043 /* We track the depth so that we know when to emit startstr/endstr on the
16044 * output. */
16045 int depth_;
16046
16047 /* Have we emitted the first element? This state is necessary to emit commas
16048 * without leaving a trailing comma in arrays/maps. We keep this state per
16049 * frame depth.
16050 *
16051 * Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages.
16052 * We count frames (contexts in which we separate elements by commas) as both
16053 * repeated fields and messages (maps), and the worst case is a
16054 * message->repeated field->submessage->repeated field->... nesting. */
16055 bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2];
16056};
16057
16058/* StringPiece; a pointer plus a length. */
16059typedef struct {
16060 char *ptr;
16061 size_t len;
16062} strpc;
16063
16064void freestrpc(void *ptr) {
16065 strpc *pc = ptr;
16066 upb_gfree(pc->ptr);
16067 upb_gfree(pc);
16068}
16069
16070/* Convert fielddef name to JSON name and return as a string piece. */
16071strpc *newstrpc(upb_handlers *h, const upb_fielddef *f,
16072 bool preserve_fieldnames) {
16073 /* TODO(haberman): handle malloc failure. */
16074 strpc *ret = upb_gmalloc(sizeof(*ret));
16075 if (preserve_fieldnames) {
16076 ret->ptr = upb_gstrdup(upb_fielddef_name(f));
16077 ret->len = strlen(ret->ptr);
16078 } else {
16079 size_t len;
16080 ret->len = upb_fielddef_getjsonname(f, NULL, 0);
16081 ret->ptr = upb_gmalloc(ret->len);
16082 len = upb_fielddef_getjsonname(f, ret->ptr, ret->len);
16083 UPB_ASSERT(len == ret->len);
16084 ret->len--; /* NULL */
16085 }
16086
16087 upb_handlers_addcleanup(h, ret, freestrpc);
16088 return ret;
16089}
16090
16091/* ------------ JSON string printing: values, maps, arrays ------------------ */
16092
16093static void print_data(
16094 upb_json_printer *p, const char *buf, unsigned int len) {
16095 /* TODO: Will need to change if we support pushback from the sink. */
16096 size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
16097 UPB_ASSERT(n == len);
16098}
16099
16100static void print_comma(upb_json_printer *p) {
16101 if (!p->first_elem_[p->depth_]) {
16102 print_data(p, ",", 1);
16103 }
16104 p->first_elem_[p->depth_] = false;
16105}
16106
16107/* Helpers that print properly formatted elements to the JSON output stream. */
16108
16109/* Used for escaping control chars in strings. */
16110static const char kControlCharLimit = 0x20;
16111
16112UPB_INLINE bool is_json_escaped(char c) {
16113 /* See RFC 4627. */
16114 unsigned char uc = (unsigned char)c;
16115 return uc < kControlCharLimit || uc == '"' || uc == '\\';
16116}
16117
16118UPB_INLINE const char* json_nice_escape(char c) {
16119 switch (c) {
16120 case '"': return "\\\"";
16121 case '\\': return "\\\\";
16122 case '\b': return "\\b";
16123 case '\f': return "\\f";
16124 case '\n': return "\\n";
16125 case '\r': return "\\r";
16126 case '\t': return "\\t";
16127 default: return NULL;
16128 }
16129}
16130
16131/* Write a properly escaped string chunk. The surrounding quotes are *not*
16132 * printed; this is so that the caller has the option of emitting the string
16133 * content in chunks. */
16134static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
16135 const char* unescaped_run = NULL;
16136 unsigned int i;
16137 for (i = 0; i < len; i++) {
16138 char c = buf[i];
16139 /* Handle escaping. */
16140 if (is_json_escaped(c)) {
16141 /* Use a "nice" escape, like \n, if one exists for this character. */
16142 const char* escape = json_nice_escape(c);
16143 /* If we don't have a specific 'nice' escape code, use a \uXXXX-style
16144 * escape. */
16145 char escape_buf[8];
16146 if (!escape) {
16147 unsigned char byte = (unsigned char)c;
16148 _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
16149 escape = escape_buf;
16150 }
16151
16152 /* N.B. that we assume that the input encoding is equal to the output
16153 * encoding (both UTF-8 for now), so for chars >= 0x20 and != \, ", we
16154 * can simply pass the bytes through. */
16155
16156 /* If there's a current run of unescaped chars, print that run first. */
16157 if (unescaped_run) {
16158 print_data(p, unescaped_run, &buf[i] - unescaped_run);
16159 unescaped_run = NULL;
16160 }
16161 /* Then print the escape code. */
16162 print_data(p, escape, strlen(escape));
16163 } else {
16164 /* Add to the current unescaped run of characters. */
16165 if (unescaped_run == NULL) {
16166 unescaped_run = &buf[i];
16167 }
16168 }
16169 }
16170
16171 /* If the string ended in a run of unescaped characters, print that last run. */
16172 if (unescaped_run) {
16173 print_data(p, unescaped_run, &buf[len] - unescaped_run);
16174 }
16175}
16176
16177#define CHKLENGTH(x) if (!(x)) return -1;
16178
16179/* Helpers that format floating point values according to our custom formats.
16180 * Right now we use %.8g and %.17g for float/double, respectively, to match
16181 * proto2::util::JsonFormat's defaults. May want to change this later. */
16182
16183const char neginf[] = "\"-Infinity\"";
16184const char inf[] = "\"Infinity\"";
16185
16186static size_t fmt_double(double val, char* buf, size_t length) {
16187 if (val == (1.0 / 0.0)) {
16188 CHKLENGTH(length >= strlen(inf));
16189 strcpy(buf, inf);
16190 return strlen(inf);
16191 } else if (val == (-1.0 / 0.0)) {
16192 CHKLENGTH(length >= strlen(neginf));
16193 strcpy(buf, neginf);
16194 return strlen(neginf);
16195 } else {
16196 size_t n = _upb_snprintf(buf, length, "%.17g", val);
16197 CHKLENGTH(n > 0 && n < length);
16198 return n;
16199 }
16200}
16201
16202static size_t fmt_float(float val, char* buf, size_t length) {
16203 size_t n = _upb_snprintf(buf, length, "%.8g", val);
16204 CHKLENGTH(n > 0 && n < length);
16205 return n;
16206}
16207
16208static size_t fmt_bool(bool val, char* buf, size_t length) {
16209 size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false"));
16210 CHKLENGTH(n > 0 && n < length);
16211 return n;
16212}
16213
16214static size_t fmt_int64(long val, char* buf, size_t length) {
16215 size_t n = _upb_snprintf(buf, length, "%ld", val);
16216 CHKLENGTH(n > 0 && n < length);
16217 return n;
16218}
16219
16220static size_t fmt_uint64(unsigned long long val, char* buf, size_t length) {
16221 size_t n = _upb_snprintf(buf, length, "%llu", val);
16222 CHKLENGTH(n > 0 && n < length);
16223 return n;
16224}
16225
16226/* Print a map key given a field name. Called by scalar field handlers and by
16227 * startseq for repeated fields. */
16228static bool putkey(void *closure, const void *handler_data) {
16229 upb_json_printer *p = closure;
16230 const strpc *key = handler_data;
16231 print_comma(p);
16232 print_data(p, "\"", 1);
16233 putstring(p, key->ptr, key->len);
16234 print_data(p, "\":", 2);
16235 return true;
16236}
16237
16238#define CHKFMT(val) if ((val) == (size_t)-1) return false;
16239#define CHK(val) if (!(val)) return false;
16240
16241#define TYPE_HANDLERS(type, fmt_func) \
16242 static bool put##type(void *closure, const void *handler_data, type val) { \
16243 upb_json_printer *p = closure; \
16244 char data[64]; \
16245 size_t length = fmt_func(val, data, sizeof(data)); \
16246 UPB_UNUSED(handler_data); \
16247 CHKFMT(length); \
16248 print_data(p, data, length); \
16249 return true; \
16250 } \
16251 static bool scalar_##type(void *closure, const void *handler_data, \
16252 type val) { \
16253 CHK(putkey(closure, handler_data)); \
16254 CHK(put##type(closure, handler_data, val)); \
16255 return true; \
16256 } \
16257 static bool repeated_##type(void *closure, const void *handler_data, \
16258 type val) { \
16259 upb_json_printer *p = closure; \
16260 print_comma(p); \
16261 CHK(put##type(closure, handler_data, val)); \
16262 return true; \
16263 }
16264
16265#define TYPE_HANDLERS_MAPKEY(type, fmt_func) \
16266 static bool putmapkey_##type(void *closure, const void *handler_data, \
16267 type val) { \
16268 upb_json_printer *p = closure; \
16269 print_data(p, "\"", 1); \
16270 CHK(put##type(closure, handler_data, val)); \
16271 print_data(p, "\":", 2); \
16272 return true; \
16273 }
16274
16275TYPE_HANDLERS(double, fmt_double)
16276TYPE_HANDLERS(float, fmt_float)
16277TYPE_HANDLERS(bool, fmt_bool)
16278TYPE_HANDLERS(int32_t, fmt_int64)
16279TYPE_HANDLERS(uint32_t, fmt_int64)
16280TYPE_HANDLERS(int64_t, fmt_int64)
16281TYPE_HANDLERS(uint64_t, fmt_uint64)
16282
16283/* double and float are not allowed to be map keys. */
16284TYPE_HANDLERS_MAPKEY(bool, fmt_bool)
16285TYPE_HANDLERS_MAPKEY(int32_t, fmt_int64)
16286TYPE_HANDLERS_MAPKEY(uint32_t, fmt_int64)
16287TYPE_HANDLERS_MAPKEY(int64_t, fmt_int64)
16288TYPE_HANDLERS_MAPKEY(uint64_t, fmt_uint64)
16289
16290#undef TYPE_HANDLERS
16291#undef TYPE_HANDLERS_MAPKEY
16292
16293typedef struct {
16294 void *keyname;
16295 const upb_enumdef *enumdef;
16296} EnumHandlerData;
16297
16298static bool scalar_enum(void *closure, const void *handler_data,
16299 int32_t val) {
16300 const EnumHandlerData *hd = handler_data;
16301 upb_json_printer *p = closure;
16302 const char *symbolic_name;
16303
16304 CHK(putkey(closure, hd->keyname));
16305
16306 symbolic_name = upb_enumdef_iton(hd->enumdef, val);
16307 if (symbolic_name) {
16308 print_data(p, "\"", 1);
16309 putstring(p, symbolic_name, strlen(symbolic_name));
16310 print_data(p, "\"", 1);
16311 } else {
16312 putint32_t(closure, NULL, val);
16313 }
16314
16315 return true;
16316}
16317
16318static void print_enum_symbolic_name(upb_json_printer *p,
16319 const upb_enumdef *def,
16320 int32_t val) {
16321 const char *symbolic_name = upb_enumdef_iton(def, val);
16322 if (symbolic_name) {
16323 print_data(p, "\"", 1);
16324 putstring(p, symbolic_name, strlen(symbolic_name));
16325 print_data(p, "\"", 1);
16326 } else {
16327 putint32_t(p, NULL, val);
16328 }
16329}
16330
16331static bool repeated_enum(void *closure, const void *handler_data,
16332 int32_t val) {
16333 const EnumHandlerData *hd = handler_data;
16334 upb_json_printer *p = closure;
16335 print_comma(p);
16336
16337 print_enum_symbolic_name(p, hd->enumdef, val);
16338
16339 return true;
16340}
16341
16342static bool mapvalue_enum(void *closure, const void *handler_data,
16343 int32_t val) {
16344 const EnumHandlerData *hd = handler_data;
16345 upb_json_printer *p = closure;
16346
16347 print_enum_symbolic_name(p, hd->enumdef, val);
16348
16349 return true;
16350}
16351
16352static void *scalar_startsubmsg(void *closure, const void *handler_data) {
16353 return putkey(closure, handler_data) ? closure : UPB_BREAK;
16354}
16355
16356static void *repeated_startsubmsg(void *closure, const void *handler_data) {
16357 upb_json_printer *p = closure;
16358 UPB_UNUSED(handler_data);
16359 print_comma(p);
16360 return closure;
16361}
16362
16363static void start_frame(upb_json_printer *p) {
16364 p->depth_++;
16365 p->first_elem_[p->depth_] = true;
16366 print_data(p, "{", 1);
16367}
16368
16369static void end_frame(upb_json_printer *p) {
16370 print_data(p, "}", 1);
16371 p->depth_--;
16372}
16373
16374static bool printer_startmsg(void *closure, const void *handler_data) {
16375 upb_json_printer *p = closure;
16376 UPB_UNUSED(handler_data);
16377 if (p->depth_ == 0) {
16378 upb_bytessink_start(p->output_, 0, &p->subc_);
16379 }
16380 start_frame(p);
16381 return true;
16382}
16383
16384static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) {
16385 upb_json_printer *p = closure;
16386 UPB_UNUSED(handler_data);
16387 UPB_UNUSED(s);
16388 end_frame(p);
16389 if (p->depth_ == 0) {
16390 upb_bytessink_end(p->output_);
16391 }
16392 return true;
16393}
16394
16395static void *startseq(void *closure, const void *handler_data) {
16396 upb_json_printer *p = closure;
16397 CHK(putkey(closure, handler_data));
16398 p->depth_++;
16399 p->first_elem_[p->depth_] = true;
16400 print_data(p, "[", 1);
16401 return closure;
16402}
16403
16404static bool endseq(void *closure, const void *handler_data) {
16405 upb_json_printer *p = closure;
16406 UPB_UNUSED(handler_data);
16407 print_data(p, "]", 1);
16408 p->depth_--;
16409 return true;
16410}
16411
16412static void *startmap(void *closure, const void *handler_data) {
16413 upb_json_printer *p = closure;
16414 CHK(putkey(closure, handler_data));
16415 p->depth_++;
16416 p->first_elem_[p->depth_] = true;
16417 print_data(p, "{", 1);
16418 return closure;
16419}
16420
16421static bool endmap(void *closure, const void *handler_data) {
16422 upb_json_printer *p = closure;
16423 UPB_UNUSED(handler_data);
16424 print_data(p, "}", 1);
16425 p->depth_--;
16426 return true;
16427}
16428
16429static size_t putstr(void *closure, const void *handler_data, const char *str,
16430 size_t len, const upb_bufhandle *handle) {
16431 upb_json_printer *p = closure;
16432 UPB_UNUSED(handler_data);
16433 UPB_UNUSED(handle);
16434 putstring(p, str, len);
16435 return len;
16436}
16437
16438/* This has to Base64 encode the bytes, because JSON has no "bytes" type. */
16439static size_t putbytes(void *closure, const void *handler_data, const char *str,
16440 size_t len, const upb_bufhandle *handle) {
16441 upb_json_printer *p = closure;
16442
16443 /* This is the regular base64, not the "web-safe" version. */
16444 static const char base64[] =
16445 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
16446
16447 /* Base64-encode. */
16448 char data[16000];
16449 const char *limit = data + sizeof(data);
16450 const unsigned char *from = (const unsigned char*)str;
16451 char *to = data;
16452 size_t remaining = len;
16453 size_t bytes;
16454
16455 UPB_UNUSED(handler_data);
16456 UPB_UNUSED(handle);
16457
16458 while (remaining > 2) {
16459 /* TODO(haberman): handle encoded lengths > sizeof(data) */
16460 UPB_ASSERT((limit - to) >= 4);
16461
16462 to[0] = base64[from[0] >> 2];
16463 to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
16464 to[2] = base64[((from[1] & 0xf) << 2) | (from[2] >> 6)];
16465 to[3] = base64[from[2] & 0x3f];
16466
16467 remaining -= 3;
16468 to += 4;
16469 from += 3;
16470 }
16471
16472 switch (remaining) {
16473 case 2:
16474 to[0] = base64[from[0] >> 2];
16475 to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
16476 to[2] = base64[(from[1] & 0xf) << 2];
16477 to[3] = '=';
16478 to += 4;
16479 from += 2;
16480 break;
16481 case 1:
16482 to[0] = base64[from[0] >> 2];
16483 to[1] = base64[((from[0] & 0x3) << 4)];
16484 to[2] = '=';
16485 to[3] = '=';
16486 to += 4;
16487 from += 1;
16488 break;
16489 }
16490
16491 bytes = to - data;
16492 print_data(p, "\"", 1);
16493 putstring(p, data, bytes);
16494 print_data(p, "\"", 1);
16495 return len;
16496}
16497
16498static void *scalar_startstr(void *closure, const void *handler_data,
16499 size_t size_hint) {
16500 upb_json_printer *p = closure;
16501 UPB_UNUSED(handler_data);
16502 UPB_UNUSED(size_hint);
16503 CHK(putkey(closure, handler_data));
16504 print_data(p, "\"", 1);
16505 return p;
16506}
16507
16508static size_t scalar_str(void *closure, const void *handler_data,
16509 const char *str, size_t len,
16510 const upb_bufhandle *handle) {
16511 CHK(putstr(closure, handler_data, str, len, handle));
16512 return len;
16513}
16514
16515static bool scalar_endstr(void *closure, const void *handler_data) {
16516 upb_json_printer *p = closure;
16517 UPB_UNUSED(handler_data);
16518 print_data(p, "\"", 1);
16519 return true;
16520}
16521
16522static void *repeated_startstr(void *closure, const void *handler_data,
16523 size_t size_hint) {
16524 upb_json_printer *p = closure;
16525 UPB_UNUSED(handler_data);
16526 UPB_UNUSED(size_hint);
16527 print_comma(p);
16528 print_data(p, "\"", 1);
16529 return p;
16530}
16531
16532static size_t repeated_str(void *closure, const void *handler_data,
16533 const char *str, size_t len,
16534 const upb_bufhandle *handle) {
16535 CHK(putstr(closure, handler_data, str, len, handle));
16536 return len;
16537}
16538
16539static bool repeated_endstr(void *closure, const void *handler_data) {
16540 upb_json_printer *p = closure;
16541 UPB_UNUSED(handler_data);
16542 print_data(p, "\"", 1);
16543 return true;
16544}
16545
16546static void *mapkeyval_startstr(void *closure, const void *handler_data,
16547 size_t size_hint) {
16548 upb_json_printer *p = closure;
16549 UPB_UNUSED(handler_data);
16550 UPB_UNUSED(size_hint);
16551 print_data(p, "\"", 1);
16552 return p;
16553}
16554
16555static size_t mapkey_str(void *closure, const void *handler_data,
16556 const char *str, size_t len,
16557 const upb_bufhandle *handle) {
16558 CHK(putstr(closure, handler_data, str, len, handle));
16559 return len;
16560}
16561
16562static bool mapkey_endstr(void *closure, const void *handler_data) {
16563 upb_json_printer *p = closure;
16564 UPB_UNUSED(handler_data);
16565 print_data(p, "\":", 2);
16566 return true;
16567}
16568
16569static bool mapvalue_endstr(void *closure, const void *handler_data) {
16570 upb_json_printer *p = closure;
16571 UPB_UNUSED(handler_data);
16572 print_data(p, "\"", 1);
16573 return true;
16574}
16575
16576static size_t scalar_bytes(void *closure, const void *handler_data,
16577 const char *str, size_t len,
16578 const upb_bufhandle *handle) {
16579 CHK(putkey(closure, handler_data));
16580 CHK(putbytes(closure, handler_data, str, len, handle));
16581 return len;
16582}
16583
16584static size_t repeated_bytes(void *closure, const void *handler_data,
16585 const char *str, size_t len,
16586 const upb_bufhandle *handle) {
16587 upb_json_printer *p = closure;
16588 print_comma(p);
16589 CHK(putbytes(closure, handler_data, str, len, handle));
16590 return len;
16591}
16592
16593static size_t mapkey_bytes(void *closure, const void *handler_data,
16594 const char *str, size_t len,
16595 const upb_bufhandle *handle) {
16596 upb_json_printer *p = closure;
16597 CHK(putbytes(closure, handler_data, str, len, handle));
16598 print_data(p, ":", 1);
16599 return len;
16600}
16601
16602static void set_enum_hd(upb_handlers *h,
16603 const upb_fielddef *f,
16604 bool preserve_fieldnames,
16605 upb_handlerattr *attr) {
16606 EnumHandlerData *hd = upb_gmalloc(sizeof(EnumHandlerData));
16607 hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
16608 hd->keyname = newstrpc(h, f, preserve_fieldnames);
16609 upb_handlers_addcleanup(h, hd, upb_gfree);
16610 upb_handlerattr_sethandlerdata(attr, hd);
16611}
16612
16613/* Set up handlers for a mapentry submessage (i.e., an individual key/value pair
16614 * in a map).
16615 *
16616 * TODO: Handle missing key, missing value, out-of-order key/value, or repeated
16617 * key or value cases properly. The right way to do this is to allocate a
16618 * temporary structure at the start of a mapentry submessage, store key and
16619 * value data in it as key and value handlers are called, and then print the
16620 * key/value pair once at the end of the submessage. If we don't do this, we
16621 * should at least detect the case and throw an error. However, so far all of
16622 * our sources that emit mapentry messages do so canonically (with one key
16623 * field, and then one value field), so this is not a pressing concern at the
16624 * moment. */
16625void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames,
16626 upb_handlers *h) {
16627 const upb_msgdef *md = upb_handlers_msgdef(h);
16628
16629 /* A mapentry message is printed simply as '"key": value'. Rather than
16630 * special-case key and value for every type below, we just handle both
16631 * fields explicitly here. */
16632 const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY);
16633 const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE);
16634
16635 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
16636
16637 UPB_UNUSED(closure);
16638
16639 switch (upb_fielddef_type(key_field)) {
16640 case UPB_TYPE_INT32:
16641 upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr);
16642 break;
16643 case UPB_TYPE_INT64:
16644 upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr);
16645 break;
16646 case UPB_TYPE_UINT32:
16647 upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr);
16648 break;
16649 case UPB_TYPE_UINT64:
16650 upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr);
16651 break;
16652 case UPB_TYPE_BOOL:
16653 upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr);
16654 break;
16655 case UPB_TYPE_STRING:
16656 upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr);
16657 upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr);
16658 upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr);
16659 break;
16660 case UPB_TYPE_BYTES:
16661 upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr);
16662 break;
16663 default:
16664 UPB_ASSERT(false);
16665 break;
16666 }
16667
16668 switch (upb_fielddef_type(value_field)) {
16669 case UPB_TYPE_INT32:
16670 upb_handlers_setint32(h, value_field, putint32_t, &empty_attr);
16671 break;
16672 case UPB_TYPE_INT64:
16673 upb_handlers_setint64(h, value_field, putint64_t, &empty_attr);
16674 break;
16675 case UPB_TYPE_UINT32:
16676 upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr);
16677 break;
16678 case UPB_TYPE_UINT64:
16679 upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr);
16680 break;
16681 case UPB_TYPE_BOOL:
16682 upb_handlers_setbool(h, value_field, putbool, &empty_attr);
16683 break;
16684 case UPB_TYPE_FLOAT:
16685 upb_handlers_setfloat(h, value_field, putfloat, &empty_attr);
16686 break;
16687 case UPB_TYPE_DOUBLE:
16688 upb_handlers_setdouble(h, value_field, putdouble, &empty_attr);
16689 break;
16690 case UPB_TYPE_STRING:
16691 upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr);
16692 upb_handlers_setstring(h, value_field, putstr, &empty_attr);
16693 upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr);
16694 break;
16695 case UPB_TYPE_BYTES:
16696 upb_handlers_setstring(h, value_field, putbytes, &empty_attr);
16697 break;
16698 case UPB_TYPE_ENUM: {
16699 upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
16700 set_enum_hd(h, value_field, preserve_fieldnames, &enum_attr);
16701 upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
16702 upb_handlerattr_uninit(&enum_attr);
16703 break;
16704 }
16705 case UPB_TYPE_MESSAGE:
16706 /* No handler necessary -- the submsg handlers will print the message
16707 * as appropriate. */
16708 break;
16709 }
16710
16711 upb_handlerattr_uninit(&empty_attr);
16712}
16713
16714void printer_sethandlers(const void *closure, upb_handlers *h) {
16715 const upb_msgdef *md = upb_handlers_msgdef(h);
16716 bool is_mapentry = upb_msgdef_mapentry(md);
16717 upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
16718 upb_msg_field_iter i;
16719 const bool *preserve_fieldnames_ptr = closure;
16720 const bool preserve_fieldnames = *preserve_fieldnames_ptr;
16721
16722 if (is_mapentry) {
16723 /* mapentry messages are sufficiently different that we handle them
16724 * separately. */
16725 printer_sethandlers_mapentry(closure, preserve_fieldnames, h);
16726 return;
16727 }
16728
16729 upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
16730 upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
16731
16732#define TYPE(type, name, ctype) \
16733 case type: \
16734 if (upb_fielddef_isseq(f)) { \
16735 upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
16736 } else { \
16737 upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
16738 } \
16739 break;
16740
16741 upb_msg_field_begin(&i, md);
16742 for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
16743 const upb_fielddef *f = upb_msg_iter_field(&i);
16744
16745 upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
16746 upb_handlerattr_sethandlerdata(&name_attr,
16747 newstrpc(h, f, preserve_fieldnames));
16748
16749 if (upb_fielddef_ismap(f)) {
16750 upb_handlers_setstartseq(h, f, startmap, &name_attr);
16751 upb_handlers_setendseq(h, f, endmap, &name_attr);
16752 } else if (upb_fielddef_isseq(f)) {
16753 upb_handlers_setstartseq(h, f, startseq, &name_attr);
16754 upb_handlers_setendseq(h, f, endseq, &empty_attr);
16755 }
16756
16757 switch (upb_fielddef_type(f)) {
16758 TYPE(UPB_TYPE_FLOAT, float, float);
16759 TYPE(UPB_TYPE_DOUBLE, double, double);
16760 TYPE(UPB_TYPE_BOOL, bool, bool);
16761 TYPE(UPB_TYPE_INT32, int32, int32_t);
16762 TYPE(UPB_TYPE_UINT32, uint32, uint32_t);
16763 TYPE(UPB_TYPE_INT64, int64, int64_t);
16764 TYPE(UPB_TYPE_UINT64, uint64, uint64_t);
16765 case UPB_TYPE_ENUM: {
16766 /* For now, we always emit symbolic names for enums. We may want an
16767 * option later to control this behavior, but we will wait for a real
16768 * need first. */
16769 upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
16770 set_enum_hd(h, f, preserve_fieldnames, &enum_attr);
16771
16772 if (upb_fielddef_isseq(f)) {
16773 upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
16774 } else {
16775 upb_handlers_setint32(h, f, scalar_enum, &enum_attr);
16776 }
16777
16778 upb_handlerattr_uninit(&enum_attr);
16779 break;
16780 }
16781 case UPB_TYPE_STRING:
16782 if (upb_fielddef_isseq(f)) {
16783 upb_handlers_setstartstr(h, f, repeated_startstr, &empty_attr);
16784 upb_handlers_setstring(h, f, repeated_str, &empty_attr);
16785 upb_handlers_setendstr(h, f, repeated_endstr, &empty_attr);
16786 } else {
16787 upb_handlers_setstartstr(h, f, scalar_startstr, &name_attr);
16788 upb_handlers_setstring(h, f, scalar_str, &empty_attr);
16789 upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
16790 }
16791 break;
16792 case UPB_TYPE_BYTES:
16793 /* XXX: this doesn't support strings that span buffers yet. The base64
16794 * encoder will need to be made resumable for this to work properly. */
16795 if (upb_fielddef_isseq(f)) {
16796 upb_handlers_setstring(h, f, repeated_bytes, &empty_attr);
16797 } else {
16798 upb_handlers_setstring(h, f, scalar_bytes, &name_attr);
16799 }
16800 break;
16801 case UPB_TYPE_MESSAGE:
16802 if (upb_fielddef_isseq(f)) {
16803 upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &name_attr);
16804 } else {
16805 upb_handlers_setstartsubmsg(h, f, scalar_startsubmsg, &name_attr);
16806 }
16807 break;
16808 }
16809
16810 upb_handlerattr_uninit(&name_attr);
16811 }
16812
16813 upb_handlerattr_uninit(&empty_attr);
16814#undef TYPE
16815}
16816
16817static void json_printer_reset(upb_json_printer *p) {
16818 p->depth_ = 0;
16819}
16820
16821
16822/* Public API *****************************************************************/
16823
16824upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h,
16825 upb_bytessink *output) {
16826#ifndef NDEBUG
16827 size_t size_before = upb_env_bytesallocated(e);
16828#endif
16829
16830 upb_json_printer *p = upb_env_malloc(e, sizeof(upb_json_printer));
16831 if (!p) return NULL;
16832
16833 p->output_ = output;
16834 json_printer_reset(p);
16835 upb_sink_reset(&p->input_, h, p);
16836
16837 /* If this fails, increase the value in printer.h. */
16838 UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(e) - size_before <=
16839 UPB_JSON_PRINTER_SIZE);
16840 return p;
16841}
16842
16843upb_sink *upb_json_printer_input(upb_json_printer *p) {
16844 return &p->input_;
16845}
16846
16847const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
16848 bool preserve_fieldnames,
16849 const void *owner) {
16850 return upb_handlers_newfrozen(
16851 md, owner, printer_sethandlers, &preserve_fieldnames);
16852}