summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2011-03-20 13:13:51 -0700
committerJosh Haberman <jhaberman@gmail.com>2011-03-20 13:13:51 -0700
commit8ef6873e0e14309a1715a252a650bab0ae1a33ef (patch)
treea9f81f9fa3ee24b923310cef964c1cbe1bf47a19 /src
parent37e1c3102be15f1e57805e828993156e3492d764 (diff)
upb_stream: all callbacks registered ahead-of-time.
This is a significant change to the upb_stream protocol, and should hopefully be the last significant change. All callbacks are now registered ahead-of-time instead of having delegated callbacks registered at runtime, which makes it much easier to aggressively optimize ahead-of-time (like with a JIT). Other impacts of this change: - You no longer need to have loaded descriptor.proto as a upb_def to load other descriptors! This means the special-case code we used for bootstrapping is no longer necessary, and we no longer need to link the descriptor for descriptor.proto into upb. - A client can now register any upb_value as what will be delivered to their value callback, not just a upb_fielddef*. This should allow for other clients to get more bang out of the streaming decoder. This change unfortunately causes a bit of a performance regression -- I think largely due to highly suboptimal code that GCC generates when structs are returned by value. See: http://blog.reverberate.org/2011/03/19/when-a-compilers-slow-code-actually-bites-you/ On the other hand, once we have a JIT this should no longer matter. Performance numbers: plain.parsestream_googlemessage1.upb_table: 374 -> 396 (5.88) plain.parsestream_googlemessage2.upb_table: 616 -> 449 (-27.11) plain.parsetostruct_googlemessage1.upb_table_byref: 268 -> 269 (0.37) plain.parsetostruct_googlemessage1.upb_table_byval: 215 -> 204 (-5.12) plain.parsetostruct_googlemessage2.upb_table_byref: 307 -> 281 (-8.47) plain.parsetostruct_googlemessage2.upb_table_byval: 297 -> 272 (-8.42) omitfp.parsestream_googlemessage1.upb_table: 423 -> 410 (-3.07) omitfp.parsestream_googlemessage2.upb_table: 679 -> 483 (-28.87) omitfp.parsetostruct_googlemessage1.upb_table_byref: 287 -> 282 (-1.74) omitfp.parsetostruct_googlemessage1.upb_table_byval: 226 -> 219 (-3.10) omitfp.parsetostruct_googlemessage2.upb_table_byref: 315 -> 298 (-5.40) omitfp.parsetostruct_googlemessage2.upb_table_byval: 297 -> 287 (-3.37)
Diffstat (limited to 'src')
-rw-r--r--src/descriptor.c331
-rw-r--r--src/descriptor_const.h438
-rw-r--r--src/upb.c8
-rw-r--r--src/upb.h19
-rw-r--r--src/upb_decoder.c156
-rw-r--r--src/upb_decoder.h38
-rw-r--r--src/upb_decoder_x64.asm10
-rw-r--r--src/upb_def.c705
-rw-r--r--src/upb_def.h54
-rw-r--r--src/upb_encoder.h2
-rw-r--r--src/upb_glue.c43
-rw-r--r--src/upb_msg.c122
-rw-r--r--src/upb_msg.h31
-rw-r--r--src/upb_stdio.c1
-rw-r--r--src/upb_stream.c328
-rw-r--r--src/upb_stream.h508
-rw-r--r--src/upb_stream_vtbl.h303
-rw-r--r--src/upb_strstream.c2
-rw-r--r--src/upb_table.c1
-rw-r--r--src/upb_textprinter.c38
-rw-r--r--src/upb_textprinter.h6
21 files changed, 1418 insertions, 1726 deletions
diff --git a/src/descriptor.c b/src/descriptor.c
deleted file mode 100644
index 9f30183..0000000
--- a/src/descriptor.c
+++ /dev/null
@@ -1,331 +0,0 @@
-unsigned char descriptor_pb[] = {
- 0x0a, 0xd8, 0x1e, 0x0a, 0x14, 0x73, 0x72, 0x63, 0x2f, 0x64, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x47, 0x0a, 0x11, 0x46, 0x69,
- 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
- 0x53, 0x65, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18,
- 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
- 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x03, 0x0a, 0x13,
- 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x0a, 0x04, 0x6e,
- 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x0f, 0x0a,
- 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x09, 0x12, 0x12, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64,
- 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x12, 0x36,
- 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79,
- 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
- 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x6e,
- 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d,
- 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72,
- 0x6f, 0x74, 0x6f, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69,
- 0x63, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74,
- 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
- 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08,
- 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
- 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39,
- 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x64,
- 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,
- 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xa9, 0x03,
- 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
- 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x34, 0x0a, 0x05, 0x66,
- 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74,
- 0x6f, 0x12, 0x38, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
- 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x35, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79,
- 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67,
- 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
- 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
- 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x6e,
- 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d,
- 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72,
- 0x6f, 0x74, 0x6f, 0x12, 0x48, 0x0a, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e,
- 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44,
- 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f,
- 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
- 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x6f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x2c, 0x0a, 0x0e, 0x45,
- 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67,
- 0x65, 0x12, 0x0d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x05, 0x12, 0x0b, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x05, 0x22, 0x94, 0x05, 0x0a, 0x14, 0x46, 0x69,
- 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
- 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x0a, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x0e, 0x0a, 0x06,
- 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05,
- 0x12, 0x3a, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69,
- 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f,
- 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c,
- 0x12, 0x38, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
- 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
- 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
- 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11,
- 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x06, 0x20, 0x01, 0x28, 0x09, 0x12, 0x10, 0x0a, 0x08, 0x65, 0x78, 0x74,
- 0x65, 0x6e, 0x64, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x12,
- 0x15, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x12, 0x2e,
- 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69,
- 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb6,
- 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54,
- 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01,
- 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f,
- 0x41, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45,
- 0x5f, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10,
- 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e,
- 0x54, 0x33, 0x32, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x06, 0x12,
- 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45,
- 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10,
- 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52,
- 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50,
- 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x0b, 0x12,
- 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x59, 0x54, 0x45,
- 0x53, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f,
- 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09,
- 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12,
- 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58,
- 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59,
- 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10,
- 0x10, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49,
- 0x4e, 0x54, 0x33, 0x32, 0x10, 0x11, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59,
- 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x12, 0x22,
- 0x43, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x0e,
- 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e,
- 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45,
- 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02,
- 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45,
- 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x22, 0x8c, 0x01, 0x0a,
- 0x13, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x0a, 0x04,
- 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12, 0x38,
- 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d,
- 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
- 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2d, 0x0a, 0x07,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d,
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6c, 0x0a, 0x18, 0x45,
- 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63,
- 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12,
- 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x12, 0x0e, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x05, 0x12, 0x32, 0x0a, 0x07, 0x6f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
- 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c,
- 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x90, 0x01,
- 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73,
- 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f,
- 0x12, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x12, 0x36, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
- 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
- 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72,
- 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x30,
- 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20,
- 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65,
- 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x22, 0x7f, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65,
- 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74,
- 0x6f, 0x12, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
- 0x01, 0x28, 0x09, 0x12, 0x12, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74,
- 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x12,
- 0x13, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79,
- 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x12, 0x2f, 0x0a, 0x07,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68,
- 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd5, 0x03,
- 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x12, 0x14, 0x0a, 0x0c, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x70, 0x61,
- 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x12,
- 0x1c, 0x0a, 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x65,
- 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x08, 0x20, 0x01, 0x28, 0x09, 0x12, 0x22, 0x0a, 0x13, 0x6a, 0x61, 0x76,
- 0x61, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x66,
- 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05,
- 0x66, 0x61, 0x6c, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x1d, 0x6a, 0x61, 0x76,
- 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x65,
- 0x71, 0x75, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61,
- 0x73, 0x68, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61,
- 0x6c, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x69, 0x6d,
- 0x69, 0x7a, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28,
- 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65,
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69,
- 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x3a, 0x05, 0x53, 0x50,
- 0x45, 0x45, 0x44, 0x12, 0x22, 0x0a, 0x13, 0x63, 0x63, 0x5f, 0x67, 0x65,
- 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61,
- 0x6c, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x15, 0x6a, 0x61, 0x76, 0x61, 0x5f,
- 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05,
- 0x66, 0x61, 0x6c, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x13, 0x70, 0x79, 0x5f,
- 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76,
- 0x69, 0x63, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05,
- 0x66, 0x61, 0x6c, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x14, 0x75, 0x6e, 0x69,
- 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b,
- 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74,
- 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69,
- 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50,
- 0x45, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x44,
- 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c,
- 0x4c, 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45,
- 0x10, 0x03, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80,
- 0x02, 0x22, 0xb8, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
- 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x17,
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f,
- 0x77, 0x69, 0x72, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65,
- 0x12, 0x2e, 0x0a, 0x1f, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64,
- 0x61, 0x72, 0x64, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
- 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65,
- 0x12, 0x43, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70,
- 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65,
- 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08,
- 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x94, 0x02, 0x0a,
- 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x12, 0x3a, 0x0a, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
- 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46,
- 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
- 0x43, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e,
- 0x47, 0x12, 0x0e, 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18,
- 0x02, 0x20, 0x01, 0x28, 0x08, 0x12, 0x19, 0x0a, 0x0a, 0x64, 0x65, 0x70,
- 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x14,
- 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c,
- 0x5f, 0x6d, 0x61, 0x70, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x09, 0x12, 0x43, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70,
- 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22,
- 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06,
- 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04,
- 0x43, 0x4f, 0x52, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54,
- 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x49, 0x45, 0x43, 0x45, 0x10, 0x02,
- 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22,
- 0x5d, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
- 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70,
- 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a,
- 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x62,
- 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x14, 0x75, 0x6e,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e,
- 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74,
- 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80,
- 0x80, 0x02, 0x22, 0x60, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
- 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x14,
- 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65,
- 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80,
- 0x80, 0x80, 0x80, 0x02, 0x22, 0x5f, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68,
- 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a,
- 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74,
- 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
- 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55,
- 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64,
- 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10,
- 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9e, 0x02, 0x0a, 0x13, 0x55, 0x6e,
- 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f,
- 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
- 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65,
- 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x61,
- 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x10, 0x69, 0x64,
- 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c,
- 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x12, 0x1a, 0x0a, 0x12,
- 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74,
- 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04,
- 0x12, 0x1a, 0x0a, 0x12, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65,
- 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05,
- 0x20, 0x01, 0x28, 0x03, 0x12, 0x14, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62,
- 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01,
- 0x28, 0x01, 0x12, 0x14, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
- 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c,
- 0x12, 0x17, 0x0a, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
- 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
- 0x09, 0x1a, 0x33, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72,
- 0x74, 0x12, 0x11, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61,
- 0x72, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x12, 0x14, 0x0a, 0x0c,
- 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
- 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x22, 0x7c, 0x0a, 0x0e, 0x53, 0x6f,
- 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f,
- 0x12, 0x3a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f,
- 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
- 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49,
- 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x1a, 0x2e, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x12, 0x10, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03,
- 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x04, 0x73, 0x70,
- 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01,
- 0x42, 0x29, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42,
- 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50,
- 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x48, 0x01
-};
-unsigned int descriptor_pb_len = 3931;
diff --git a/src/descriptor_const.h b/src/descriptor_const.h
index f02eb75..228c95a 100644
--- a/src/descriptor_const.h
+++ b/src/descriptor_const.h
@@ -50,152 +50,298 @@ typedef enum google_protobuf_FileOptions_OptimizeMode {
/* Constants for field names and numbers. */
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNAME "file"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM 2
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNAME "field"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_FIELDNUM 3
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_FIELDNAME "nested_type"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_FIELDNUM 4
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_FIELDNAME "enum_type"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_FIELDNUM 5
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_FIELDNAME "extension_range"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_FIELDNUM 6
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_FIELDNAME "extension"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_FIELDNUM 7
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_FIELDNUM 1
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_FIELDNAME "path"
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_FIELDNUM 2
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_FIELDNAME "span"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_FIELDNUM 2
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_FIELDNUM 3
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_FIELDNAME "identifier_value"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE_FIELDNUM 4
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE_FIELDNAME "positive_int_value"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE_FIELDNUM 5
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE_FIELDNAME "negative_int_value"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE_FIELDNUM 6
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE_FIELDNAME "double_value"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_FIELDNUM 7
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_FIELDNAME "string_value"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_FIELDNUM 8
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_FIELDNAME "aggregate_value"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_FIELDNUM 2
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_FIELDNAME "package"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_FIELDNUM 3
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_FIELDNAME "dependency"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM 4
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNAME "message_type"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM 5
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNAME "enum_type"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_FIELDNUM 6
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_FIELDNAME "service"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_FIELDNUM 7
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_FIELDNAME "extension"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_FIELDNUM 8
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_FIELDNUM 9
-#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_FIELDNAME "source_code_info"
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_FIELDNUM 2
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_FIELDNAME "input_type"
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_FIELDNUM 3
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_FIELDNAME "output_type"
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_FIELDNUM 4
-#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM 2
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNAME "value"
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_FIELDNUM 3
-#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNUM 2
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNAME "number"
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_FIELDNUM 3
-#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_FIELDNUM 2
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_FIELDNAME "method"
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_FIELDNUM 3
-#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNUM 1
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_FIELDNAME "name_part"
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNUM 2
-#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_FIELDNAME "is_extension"
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_FIELDNUM 1
-#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_FIELDNAME "location"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_FIELDNUM 1
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_FIELDNAME "start"
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END_FIELDNUM 2
-#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END_FIELDNAME "end"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE_FIELDNAME "ctype"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_FIELDNUM 2
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_FIELDNAME "packed"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_FIELDNUM 3
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_FIELDNAME "deprecated"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_FIELDNUM 9
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_FIELDNAME "experimental_map_key"
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_FIELDNAME "java_package"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_FIELDNUM 8
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_FIELDNAME "java_outer_classname"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_FIELDNUM 9
-#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_FIELDNAME "optimize_for"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES_FIELDNUM 10
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES_FIELDNAME "java_multiple_files"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES_FIELDNUM 16
-#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES_FIELDNAME "cc_generic_services"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES_FIELDNUM 17
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES_FIELDNAME "java_generic_services"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_FIELDNUM 18
-#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_FIELDNAME "py_generic_services"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_FIELDNUM 20
-#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_FIELDNAME "java_generate_equals_and_hash"
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_FIELDNUM 1
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_FIELDNAME "message_set_wire_format"
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_FIELDNUM 2
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_FIELDNAME "no_standard_descriptor_accessor"
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_FIELDNUM 1
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_FIELDNAME "name"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_FIELDNUM 2
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_FIELDNAME "extendee"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_FIELDNUM 3
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_FIELDNAME "number"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_FIELDNUM 4
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_FIELDNAME "label"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIELDNUM 5
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIELDNAME "type"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_FIELDNUM 6
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_FIELDNAME "type_name"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_FIELDNUM 7
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_FIELDNAME "default_value"
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_FIELDNUM 8
-#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_FIELDNAME "options"
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_FIELDNUM 999
-#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE__FIELDNUM 1
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE__FIELDNAME "file"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD__FIELDNUM 2
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD__FIELDNAME "field"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE__FIELDNUM 3
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE__FIELDNAME "nested_type"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE__FIELDNUM 4
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE__FIELDNAME "enum_type"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE__FIELDNUM 5
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE__FIELDNAME "extension_range"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION__FIELDNUM 6
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION__FIELDNAME "extension"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS__FIELDNUM 7
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH__FIELDNUM 1
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH__FIELDNAME "path"
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN__FIELDNUM 2
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN__FIELDNAME "span"
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME__FIELDNUM 2
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE__FIELDNUM 3
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE__FIELDNAME "identifier_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE__FIELDNUM 4
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE__FIELDNAME "positive_int_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE__FIELDTYPE 4
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE__FIELDNUM 5
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE__FIELDNAME "negative_int_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE__FIELDTYPE 3
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE__FIELDNUM 6
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE__FIELDNAME "double_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE__FIELDTYPE 1
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE__FIELDNUM 7
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE__FIELDNAME "string_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE__FIELDTYPE 12
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE__FIELDNUM 8
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE__FIELDNAME "aggregate_value"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE__FIELDNUM 2
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE__FIELDNAME "package"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY__FIELDNUM 3
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY__FIELDNAME "dependency"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE__FIELDNUM 4
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE__FIELDNAME "message_type"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE__FIELDNUM 5
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE__FIELDNAME "enum_type"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE__FIELDNUM 6
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE__FIELDNAME "service"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION__FIELDNUM 7
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION__FIELDNAME "extension"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS__FIELDNUM 8
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO__FIELDNUM 9
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO__FIELDNAME "source_code_info"
+#define GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE__FIELDNUM 2
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE__FIELDNAME "input_type"
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE__FIELDNUM 3
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE__FIELDNAME "output_type"
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS__FIELDNUM 4
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE__FIELDNUM 2
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE__FIELDNAME "value"
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS__FIELDNUM 3
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER__FIELDNUM 2
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER__FIELDNAME "number"
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS__FIELDNUM 3
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD__FIELDNUM 2
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD__FIELDNAME "method"
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS__FIELDNUM 3
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART__FIELDNUM 1
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART__FIELDNAME "name_part"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION__FIELDNUM 2
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION__FIELDNAME "is_extension"
+#define GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION__FIELDNUM 1
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION__FIELDNAME "location"
+#define GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START__FIELDNUM 1
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START__FIELDNAME "start"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END__FIELDNUM 2
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END__FIELDNAME "end"
+#define GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE__FIELDNUM 1
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE__FIELDNAME "ctype"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE__FIELDTYPE 14
+
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED__FIELDNUM 2
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED__FIELDNAME "packed"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED__FIELDNUM 3
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED__FIELDNAME "deprecated"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY__FIELDNUM 9
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY__FIELDNAME "experimental_map_key"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE__FIELDNUM 1
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE__FIELDNAME "java_package"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME__FIELDNUM 8
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME__FIELDNAME "java_outer_classname"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR__FIELDNUM 9
+#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR__FIELDNAME "optimize_for"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR__FIELDTYPE 14
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES__FIELDNUM 10
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES__FIELDNAME "java_multiple_files"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES__FIELDNUM 16
+#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES__FIELDNAME "cc_generic_services"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES__FIELDNUM 17
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES__FIELDNAME "java_generic_services"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES__FIELDNUM 18
+#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES__FIELDNAME "py_generic_services"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH__FIELDNUM 20
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH__FIELDNAME "java_generate_equals_and_hash"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT__FIELDNUM 1
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT__FIELDNAME "message_set_wire_format"
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR__FIELDNUM 2
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR__FIELDNAME "no_standard_descriptor_accessor"
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR__FIELDTYPE 8
+
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME__FIELDNUM 1
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME__FIELDNAME "name"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE__FIELDNUM 2
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE__FIELDNAME "extendee"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER__FIELDNUM 3
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER__FIELDNAME "number"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER__FIELDTYPE 5
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL__FIELDNUM 4
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL__FIELDNAME "label"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL__FIELDTYPE 14
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE__FIELDNUM 5
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE__FIELDNAME "type"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE__FIELDTYPE 14
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME__FIELDNUM 6
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME__FIELDNAME "type_name"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE__FIELDNUM 7
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE__FIELDNAME "default_value"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE__FIELDTYPE 9
+
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS__FIELDNUM 8
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS__FIELDNAME "options"
+#define GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
+#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION__FIELDNUM 999
+#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION__FIELDNAME "uninterpreted_option"
+#define GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION__FIELDTYPE 11
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/upb.c b/src/upb.c
index 6bb1ccc..fdf5c07 100644
--- a/src/upb.c
+++ b/src/upb.c
@@ -8,7 +8,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
-
+#include "descriptor_const.h"
#include "upb.h"
#include "upb_string.h"
@@ -40,6 +40,12 @@ const upb_type_info upb_types[] = {
TYPE_INFO(UPB_WIRE_TYPE_VARINT, int64_t, 1, INT64) // SINT64
};
+#ifdef NDEBUG
+upb_value UPB_NO_VALUE = {{0}};
+#else
+upb_value UPB_NO_VALUE = {{0}, UPB_VALUETYPE_RAW};
+#endif
+
void upb_seterr(upb_status *status, enum upb_status_code code,
const char *msg, ...) {
status->code = code;
diff --git a/src/upb.h b/src/upb.h
index c8d707d..01de8cf 100644
--- a/src/upb.h
+++ b/src/upb.h
@@ -46,11 +46,15 @@ INLINE size_t upb_align_up(size_t val, size_t align) {
// The maximum that any submessages can be nested. Matches proto2's limit.
+// At the moment this specifies the size of several statically-sized arrays
+// and therefore setting it high will cause more memory to be used. Will
+// be replaced by a runtime-configurable limit and dynamically-resizing arrays.
#define UPB_MAX_NESTING 64
// The maximum number of fields that any one .proto type can have. Note that
// this is very different than the max field number. It is hard to imagine a
-// scenario where more than 32k fields makes sense.
+// scenario where more than 32k fields (each with its own name and field number)
+// makes sense.
#define UPB_MAX_FIELDS (1<<15)
typedef int16_t upb_field_count_t;
@@ -72,7 +76,9 @@ typedef int16_t upb_field_count_t;
// The maximum depth that the type graph can have. Note that this setting does
// not automatically constrain UPB_MAX_NESTING, because type cycles allow for
-// unlimited nesting if we do not limit it.
+// unlimited nesting if we do not limit it. Many algorithms in upb call
+// recursive functions that traverse the type graph, so we must limit this to
+// avoid blowing the C stack.
#define UPB_MAX_TYPE_DEPTH 64
// The biggest possible single value is a 10-byte varint.
@@ -145,6 +151,8 @@ struct _upb_msg;
typedef struct _upb_msg upb_msg;
struct _upb_bytesrc;
typedef struct _upb_bytesrc upb_bytesrc;
+struct _upb_fielddef;
+typedef struct _upb_fielddef upb_fielddef;
typedef int32_t upb_strlen_t;
#define UPB_STRLEN_MAX INT32_MAX
@@ -155,23 +163,25 @@ typedef uint8_t upb_valuetype_t;
#define UPB_VALUETYPE_ARRAY 32
#define UPB_VALUETYPE_BYTESRC 32
#define UPB_VALUETYPE_RAW 33
+#define UPB_VALUETYPE_FIELDDEF 34
// A single .proto value. The owner must have an out-of-band way of knowing
// the type, so that it knows which union member to use.
typedef struct {
union {
+ uint64_t uint64;
double _double;
float _float;
int32_t int32;
int64_t int64;
uint32_t uint32;
- uint64_t uint64;
bool _bool;
upb_string *str;
upb_bytesrc *bytesrc;
upb_msg *msg;
upb_array *arr;
upb_atomic_refcount_t *refcount;
+ upb_fielddef *fielddef;
void *_void;
} val;
@@ -208,6 +218,9 @@ UPB_VALUE_ACCESSORS(str, str, upb_string*, UPB_TYPE(STRING));
UPB_VALUE_ACCESSORS(msg, msg, upb_msg*, UPB_TYPE(MESSAGE));
UPB_VALUE_ACCESSORS(arr, arr, upb_array*, UPB_VALUETYPE_ARRAY);
UPB_VALUE_ACCESSORS(bytesrc, bytesrc, upb_bytesrc*, UPB_VALUETYPE_BYTESRC);
+UPB_VALUE_ACCESSORS(fielddef, fielddef, upb_fielddef*, UPB_VALUETYPE_FIELDDEF);
+
+extern upb_value UPB_NO_VALUE;
INLINE void upb_value_setraw(upb_value *val, uint64_t cval) {
SET_TYPE(val->type, UPB_VALUETYPE_RAW);
diff --git a/src/upb_decoder.c b/src/upb_decoder.c
index dc5dafd..6fa37b4 100644
--- a/src/upb_decoder.c
+++ b/src/upb_decoder.c
@@ -4,13 +4,11 @@
* Copyright (c) 2008-2011 Joshua Haberman. See LICENSE for details.
*/
-#include "upb_decoder.h"
-#include "upb_varint_decoder.h"
-
#include <inttypes.h>
#include <stddef.h>
#include <stdlib.h>
-#include "upb_def.h"
+#include "upb_decoder.h"
+#include "upb_varint_decoder.h"
// If the return value is other than UPB_CONTINUE, that is what the last
// callback returned.
@@ -37,7 +35,12 @@ INLINE int64_t upb_zzdec_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); }
INLINE void upb_decoder_advance(upb_decoder *d, size_t len) {
d->ptr += len;
- //d->bytes_parsed_slow += len;
+}
+
+INLINE size_t upb_decoder_offset(upb_decoder *d) {
+ size_t offset = d->buf_stream_offset;
+ if (d->buf) offset += (d->ptr - upb_string_getrobuf(d->buf));
+ return offset;
}
INLINE size_t upb_decoder_bufleft(upb_decoder *d) {
@@ -45,13 +48,11 @@ INLINE size_t upb_decoder_bufleft(upb_decoder *d) {
}
INLINE void upb_dstate_setmsgend(upb_decoder *d) {
- d->submsg_end = (d->top->end_offset == UPB_GROUP_END_OFFSET) ?
- (void*)UINTPTR_MAX :
- upb_string_getrobuf(d->buf) + (d->top->end_offset - d->buf_stream_offset);
+ size_t end_offset = d->dispatcher.top->end_offset;
+ d->submsg_end = (end_offset == UPB_GROUP_END_OFFSET) ? (void*)UINTPTR_MAX :
+ d->ptr + (end_offset - upb_decoder_offset(d));
}
-static upb_flow_t upb_pop(upb_decoder *d);
-
// Called only from the slow path, this function copies the next "len" bytes
// from the stream to "data", adjusting the dstate appropriately.
static bool upb_getbuf(upb_decoder *d, void *data, size_t bytes_wanted) {
@@ -186,54 +187,44 @@ INLINE bool upb_check_type(upb_wire_type_t wt, upb_fieldtype_t ft) {
return upb_types[ft].native_wire_type == wt;
}
-static upb_flow_t upb_push(upb_decoder *d, upb_fielddef *f,
- upb_value submsg_len, upb_fieldtype_t type) {
- ++d->top;
- if(d->top >= d->limit) {
- upb_seterr(d->status, UPB_ERROR, "Nesting too deep.");
- return UPB_ERROR;
- }
- d->top->end_offset = (type == UPB_TYPE(GROUP)) ?
- UPB_GROUP_END_OFFSET :
- d->buf_stream_offset + (d->ptr - upb_string_getrobuf(d->buf)) +
- upb_value_getint32(submsg_len);
- d->top->f = f;
- d->msgdef = upb_downcast_msgdef(f->def);
+static upb_flow_t upb_pop(upb_decoder *d) {
+ upb_flow_t ret = upb_dispatch_endsubmsg(&d->dispatcher);
upb_dstate_setmsgend(d);
- upb_flow_t ret = upb_dispatch_startsubmsg(&d->dispatcher, f);
- if (ret == UPB_SKIPSUBMSG) {
- if (type == UPB_TYPE(GROUP)) {
- fprintf(stderr, "upb_decoder: Can't skip groups yet.\n");
- abort();
- }
- upb_decoder_advance(d, upb_value_getint32(submsg_len));
- --d->top;
- upb_dstate_setmsgend(d);
- ret = UPB_CONTINUE;
- }
return ret;
}
-static upb_flow_t upb_pop(upb_decoder *d) {
- --d->top;
- d->msgdef = upb_downcast_msgdef(d->top->f->def);
+static upb_flow_t upb_decoder_skipsubmsg(upb_decoder *d) {
+ if (d->dispatcher.top->f->type == UPB_TYPE(GROUP)) {
+ fprintf(stderr, "upb_decoder: Can't skip groups yet.\n");
+ abort();
+ }
+ upb_decoder_advance(d, d->dispatcher.top->end_offset - d->buf_stream_offset -
+ (d->ptr - upb_string_getrobuf(d->buf)));
+ upb_pop(d);
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_push(upb_decoder *d, upb_handlers_fieldent *f,
+ upb_value submsg_len) {
+ upb_flow_t flow = upb_dispatch_startsubmsg(&d->dispatcher, f,
+ (f->type == UPB_TYPE(GROUP)) ? UPB_GROUP_END_OFFSET :
+ upb_decoder_offset(d) + upb_value_getint32(submsg_len));
upb_dstate_setmsgend(d);
- return upb_dispatch_endsubmsg(&d->dispatcher, d->top->f);
+ return flow;
}
-void upb_decoder_run(upb_src *src, upb_status *status) {
- upb_decoder *d = (upb_decoder*)src;
+void upb_decoder_decode(upb_decoder *d, upb_status *status) {
d->status = status;
- d->ptr = NULL;
- d->end = NULL; // Force a buffer pull.
- d->submsg_end = (void*)0x1; // But don't let end-of-message get triggered.
- d->msgdef = upb_downcast_msgdef(d->top->f->def);
-// TODO: handle UPB_SKIPSUBMSG
-#define CHECK_FLOW(expr) if ((expr) == UPB_BREAK) { /*assert(!upb_ok(status));*/ goto callback_err; }
+#define CHECK_FLOW(expr) \
+ switch (expr) { \
+ case UPB_BREAK: goto callback_err; \
+ case UPB_SKIPSUBMSG: upb_decoder_skipsubmsg(d); continue; \
+ default: break; /* continue normally. */ \
+ }
#define CHECK(expr) if (!expr) { assert(!upb_ok(status)); goto err; }
- CHECK_FLOW(upb_dispatch_startmsg(&d->dispatcher));
+ if (upb_dispatch_startmsg(&d->dispatcher, d->closure) != UPB_CONTINUE) goto err;
// Main loop: executed once per tag/field pair.
while(1) {
@@ -261,10 +252,10 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
// Parse/handle tag.
upb_tag tag;
if (!upb_decode_tag(d, &tag)) {
- if (status->code == UPB_EOF && d->top == d->stack) {
+ if (status->code == UPB_EOF && upb_dispatcher_stackempty(&d->dispatcher)) {
// Normal end-of-file.
upb_clearerr(status);
- CHECK_FLOW(upb_dispatch_endmsg(&d->dispatcher));
+ upb_dispatch_endmsg(&d->dispatcher, status);
return;
} else {
if (status->code == UPB_EOF) {
@@ -282,7 +273,7 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
case UPB_WIRE_TYPE_START_GROUP:
break; // Nothing to do now, below we will push appropriately.
case UPB_WIRE_TYPE_END_GROUP:
- if(d->top->end_offset != UPB_GROUP_END_OFFSET) {
+ if(d->dispatcher.top->end_offset != UPB_GROUP_END_OFFSET) {
upb_seterr(status, UPB_ERROR, "Unexpected END_GROUP tag.");
goto err;
}
@@ -302,41 +293,38 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
}
// Look up field by tag number.
- upb_itof_ent *e = upb_msgdef_itofent(d->msgdef, tag.field_number);
+ upb_dispatcher_field *f =
+ upb_dispatcher_lookup(&d->dispatcher, tag.field_number);
- if (!e) {
+ if (!f) {
if (tag.wire_type == UPB_WIRE_TYPE_DELIMITED)
CHECK(upb_decode_string(d, &val, &d->tmp));
CHECK_FLOW(upb_dispatch_unknownval(&d->dispatcher, tag.field_number, val));
continue;
}
- upb_fielddef *f = e->f;
- assert(e->field_type == f->type);
- assert(e->native_wire_type == upb_types[f->type].native_wire_type);
-
- if (tag.wire_type != e->native_wire_type) {
+ if (tag.wire_type != f->native_wire_type) {
// TODO: Support packed fields.
- upb_seterr(status, UPB_ERROR, "Field had incorrect type, name: " UPB_STRFMT
- ", field type: %d, expected wire type %d, actual wire type: %d",
- UPB_STRARG(f->name), f->type, upb_types[f->type].native_wire_type,
- tag.wire_type);
- upb_printerr(status);
+ upb_seterr(status, UPB_ERROR, "Field had incorrect type, field number: %d"
+ ", field type: %d, expected wire type: %d, "
+ "actual wire type: %d, offset: %d",
+ tag.field_number, f->type, upb_types[f->type].native_wire_type,
+ tag.wire_type, upb_decoder_offset(d));
goto err;
}
- // Perform any further massaging of the data now that we have the fielddef.
- // Now we can distinguish strings from submessages, and we know about
- // zig-zag-encoded types.
+ // Perform any further massaging of the data now that we have the field's
+ // type. Now we can distinguish strings from submessages, and we know
+ // about zig-zag-encoded types.
// TODO: handle packed encoding.
// TODO: if we were being paranoid, we could check for 32-bit-varint types
// that the top 32 bits all match the highest bit of the low 32 bits.
// If this is not true we are losing data. But the main protobuf library
// doesn't check this, and it would slow us down, so pass for now.
- switch (e->field_type) {
+ switch (f->type) {
case UPB_TYPE(MESSAGE):
case UPB_TYPE(GROUP):
- CHECK_FLOW(upb_push(d, f, val, e->field_type));
+ CHECK_FLOW(upb_push(d, f, val));
continue; // We have no value to dispatch.
case UPB_TYPE(STRING):
case UPB_TYPE(BYTES):
@@ -358,7 +346,6 @@ void upb_decoder_run(upb_src *src, upb_status *status) {
}
callback_err:
- upb_copyerr(status, d->dispatcher.top->handlers.status);
if (upb_ok(status)) {
upb_seterr(status, UPB_ERROR, "Callback returned UPB_BREAK");
}
@@ -366,37 +353,24 @@ err:
assert(!upb_ok(status));
}
-void upb_decoder_sethandlers(upb_src *src, upb_handlers *handlers) {
- upb_decoder *d = (upb_decoder*)src;
- upb_dispatcher_reset(&d->dispatcher, handlers, true);
- d->top = d->stack;
- d->buf_stream_offset = 0;
-}
-
-void upb_decoder_init(upb_decoder *d, upb_msgdef *msgdef) {
- static upb_src_vtbl vtbl = {
- &upb_decoder_sethandlers,
- &upb_decoder_run,
- };
- upb_src_init(&d->src, &vtbl);
- upb_dispatcher_init(&d->dispatcher);
- d->f.def = UPB_UPCAST(msgdef);
- d->stack[0].f = &d->f;
- // Never want to end top-level message, so treat it like a group.
- d->stack[0].end_offset = UPB_GROUP_END_OFFSET;
- d->limit = &d->stack[UPB_MAX_NESTING];
+void upb_decoder_init(upb_decoder *d, upb_handlers *handlers) {
+ upb_dispatcher_init(&d->dispatcher, handlers, UPB_GROUP_END_OFFSET);
d->buf = NULL;
d->tmp = NULL;
}
-void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc) {
+void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc, void *closure) {
d->bytesrc = bytesrc;
- d->top = &d->stack[0];
+ d->closure = closure;
+ upb_dispatcher_reset(&d->dispatcher);
+ d->ptr = NULL;
+ d->end = NULL; // Force a buffer pull.
+ d->submsg_end = (void*)0x1; // But don't let end-of-message get triggered.
+ d->buf_stream_offset = 0;
}
void upb_decoder_uninit(upb_decoder *d) {
+ upb_dispatcher_uninit(&d->dispatcher);
upb_string_unref(d->buf);
upb_string_unref(d->tmp);
}
-
-upb_src *upb_decoder_src(upb_decoder *d) { return &d->src; }
diff --git a/src/upb_decoder.h b/src/upb_decoder.h
index 98b1b94..af2124c 100644
--- a/src/upb_decoder.h
+++ b/src/upb_decoder.h
@@ -18,7 +18,6 @@
#include <stdbool.h>
#include <stdint.h>
-#include "upb_def.h"
#include "upb_stream.h"
#ifdef __cplusplus
@@ -27,31 +26,17 @@ extern "C" {
/* upb_decoder *****************************************************************/
-// The decoder keeps a stack with one entry per level of recursion.
-// upb_decoder_frame is one frame of that stack.
-typedef struct {
- upb_fielddef *f;
- size_t end_offset; // For groups, 0.
-} upb_decoder_frame;
-
struct _upb_decoder {
- // Immutable state of the decoder.
- upb_src src;
- upb_dispatcher dispatcher;
+ // Bytesrc from which we pull serialized data.
upb_bytesrc *bytesrc;
- // Mutable state of the decoder.
-
- // Msgdef for the current level.
- upb_msgdef *msgdef;
-
- // Stack entries store the offset where the submsg ends (for groups, 0).
- upb_decoder_frame *top, *limit;
+ // Dispatcher to which we push parsed data.
+ upb_dispatcher dispatcher;
// Current input buffer.
upb_string *buf;
- // Temporary string for passing to callbacks.
+ // Temporary string for passing string data to callbacks.
upb_string *tmp;
// The offset within the overall stream represented by the *beginning* of buf.
@@ -66,12 +51,11 @@ struct _upb_decoder {
// End of this submessage, relative to *ptr.
const char *submsg_end;
+ // The closure that was passed by the caller for the top-level message.
+ void *closure;
+
// Where we will store any errors that occur.
upb_status *status;
-
- // A fake fielddef for storing the msgdef for the top-level message.
- upb_fielddef f;
- upb_decoder_frame stack[UPB_MAX_NESTING];
};
// A upb_decoder decodes the binary protocol buffer format, writing the data it
@@ -80,18 +64,16 @@ struct _upb_decoder;
typedef struct _upb_decoder upb_decoder;
// Allocates and frees a upb_decoder, respectively.
-void upb_decoder_init(upb_decoder *d, upb_msgdef *md);
+void upb_decoder_init(upb_decoder *d, upb_handlers *handlers);
void upb_decoder_uninit(upb_decoder *d);
// Resets the internal state of an already-allocated decoder. This puts it in a
// state where it has not seen any data, and expects the next data to be from
// the beginning of a new protobuf. Parsers must be reset before they can be
// used. A decoder can be reset multiple times.
-void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc);
+void upb_decoder_reset(upb_decoder *d, upb_bytesrc *bytesrc, void *closure);
-// Returns a upb_src pointer by which the decoder can be used. The returned
-// upb_src is invalidated by upb_decoder_reset() or upb_decoder_free().
-upb_src *upb_decoder_src(upb_decoder *d);
+void upb_decoder_decode(upb_decoder *d, upb_status *status);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/upb_decoder_x64.asm b/src/upb_decoder_x64.asm
index 032ea86..c417644 100644
--- a/src/upb_decoder_x64.asm
+++ b/src/upb_decoder_x64.asm
@@ -34,8 +34,8 @@ SECTION .text
%define BUF rbx ; const char *p, current buf position.
%define END rbp ; const char *end, where the buf ends (either submsg end or buf end)
%define STRING r12 ; unused
-%define FIELDDEF r13 ; upb_fielddef *f, needs to be preserved across varint decoding call.
-%define CALLBACK r14
+%define FVAL r13 ; upb_value fval, needs to be preserved across varint decoding call.
+%define UNUSED r14
%define CLOSURE r15
; Stack layout: *tableptr, uint32_t maxfield_times_8
@@ -57,10 +57,10 @@ SECTION .text
; path that goes into a tight loop if the encoding was packed).
; - check_6: the field is not a group or a message (or string, TODO)
; (this could be relaxed, but due to delegation it's a bit tricky).
-; - if the value is a string, the entire string is available in
+; - check_7: if the value is a string, the entire string is available in
; the buffer, and our cached string object can be recycled, and
; our string object already references the source buffer, so
-; absolutely no refcount twiddling is required. (check_7)
+; absolutely no refcount twiddling is required.
%macro decode_and_dispatch_ 0
@@ -78,7 +78,7 @@ align 16
; Decode a 1 or 2-byte varint -> eax.
mov cl, byte [BUF]
lea rdi, [BUF+1]
- movzx rax, cl ; Need all of rax since we're doing a 64-bit lea later.
+ movzx eax, cl
and eax, 0x7f
test cl, cl
jns .one_byte_tag ; Should be predictable if fields are in order.
diff --git a/src/upb_def.c b/src/upb_def.c
index 61d1a3e..08e5a8c 100644
--- a/src/upb_def.c
+++ b/src/upb_def.c
@@ -7,8 +7,6 @@
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
-#include "descriptor.c"
-#include "descriptor_const.h"
#include "upb_def.h"
#include "upb_msg.h"
@@ -190,16 +188,11 @@ static void upb_def_uninit(upb_def *def) {
// We use a separate object (upb_defbuilder) instead of having the defs handle
// the parse themselves because we need to store state that is only necessary
// during the building process itself.
-
-// When we are bootstrapping descriptor.proto, we must help the bare decoder out
-// by telling it when to descend into a submessage, because with the wire format
-// alone we cannot tell the difference between a submessage and a string.
//
-// TODO: In the long-term, we should bootstrap from a serialization format that
-// contains this information, so we can remove this special-case code. This
-// would involve defining a serialization format very similar to the existing
-// protobuf format, but that contains more information about the wire type.
-#define BEGIN_SUBMSG 100
+// All of the handlers registration in this file must be done using the
+// low-level upb_register_typed_* interface, since we might not have a msgdef
+// yet (in the case of bootstrapping). This makes it more laborious than it
+// will be for real users.
// upb_deflist: A little dynamic array for storing a growing list of upb_defs.
typedef struct {
@@ -257,6 +250,7 @@ struct _upb_defbuilder {
upb_defbuilder_frame stack[UPB_MAX_TYPE_DEPTH];
int stack_len;
upb_status status;
+ upb_symtab *symtab;
uint32_t number;
upb_string *name;
@@ -267,23 +261,23 @@ struct _upb_defbuilder {
upb_fielddef *f;
};
-typedef struct _upb_defbuilder upb_defbuilder;
// Forward declares for top-level file descriptors.
-static void upb_msgdef_register_DescriptorProto(upb_defbuilder *b, upb_handlers *h);
-static void upb_enumdef_register_EnumDescriptorProto(upb_defbuilder *b,
- upb_handlers *h);
-
+static void upb_msgdef_register_DescriptorProto(upb_handlers *h);
+static void upb_enumdef_register_EnumDescriptorProto(upb_handlers *h);
-static void upb_defbuilder_init(upb_defbuilder *b) {
+upb_defbuilder *upb_defbuilder_new(upb_symtab *s) {
+ upb_defbuilder *b = malloc(sizeof(*b));
upb_deflist_init(&b->defs);
upb_status_init(&b->status);
+ b->symtab = s;
b->stack_len = 0;
b->name = NULL;
b->default_string = NULL;
+ return b;
}
-static void upb_defbuilder_uninit(upb_defbuilder *b) {
+static void upb_defbuilder_free(upb_defbuilder *b) {
upb_string_unref(b->name);
upb_status_uninit(&b->status);
upb_deflist_uninit(&b->defs);
@@ -292,6 +286,7 @@ static void upb_defbuilder_uninit(upb_defbuilder *b) {
upb_defbuilder_frame *f = &b->stack[--b->stack_len];
upb_string_unref(f->name);
}
+ free(b);
}
static upb_msgdef *upb_defbuilder_top(upb_defbuilder *b) {
@@ -332,89 +327,67 @@ static upb_flow_t upb_defbuilder_FileDescriptorProto_startmsg(void *_b) {
return UPB_CONTINUE;
}
-static upb_flow_t upb_defbuilder_FileDescriptorProto_endmsg(void *_b) {
+static void upb_defbuilder_FileDescriptorProto_endmsg(void *_b,
+ upb_status *status) {
+ (void)status;
upb_defbuilder *b = _b;
upb_defbuilder_endcontainer(b);
- return UPB_CONTINUE;
}
-static upb_flow_t upb_defbuilder_FileDescriptorProto_value(void *_b,
- upb_fielddef *f,
- upb_value val) {
+static upb_flow_t upb_defbuilder_FileDescriptorProto_package(void *_b,
+ upb_value fval,
+ upb_value val) {
+ (void)fval;
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_FIELDNUM:
- upb_defbuilder_setscopename(b, upb_value_getstr(val));
- break;
- case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM:
- case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM:
- return BEGIN_SUBMSG;
- }
+ upb_defbuilder_setscopename(b, upb_value_getstr(val));
return UPB_CONTINUE;
}
-static upb_flow_t upb_defbuilder_FileDescriptorProto_startsubmsg(
- void *_b, upb_fielddef *f, upb_handlers *h) {
- upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_FIELDNUM:
- upb_msgdef_register_DescriptorProto(b, h);
- return UPB_DELEGATE;
- case GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_FIELDNUM:
- upb_enumdef_register_EnumDescriptorProto(b, h);
- return UPB_DELEGATE;
- default:
- // TODO: services and extensions.
- return UPB_SKIPSUBMSG;
- }
-}
+static void upb_defbuilder_register_FileDescriptorProto(upb_handlers *h) {
+ upb_register_startend(h, upb_defbuilder_FileDescriptorProto_startmsg,
+ upb_defbuilder_FileDescriptorProto_endmsg);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE__FIELDNUM,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE__FIELDTYPE,
+ &upb_defbuilder_FileDescriptorProto_package, UPB_NO_VALUE);
+
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE__FIELDNUM,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE__FIELDTYPE);
+ upb_msgdef_register_DescriptorProto(h);
+ upb_handlers_typed_pop(h);
-static void upb_defbuilder_register_FileDescriptorProto(upb_defbuilder *b,
- upb_handlers *h) {
- static upb_handlerset handlers = {
- &upb_defbuilder_FileDescriptorProto_startmsg,
- &upb_defbuilder_FileDescriptorProto_endmsg,
- &upb_defbuilder_FileDescriptorProto_value,
- &upb_defbuilder_FileDescriptorProto_startsubmsg,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE__FIELDNUM,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE__FIELDTYPE);
+ upb_enumdef_register_EnumDescriptorProto(h);
+ upb_handlers_typed_pop(h);
+
+ // TODO: services and extensions.
}
// Handlers for google.protobuf.FileDescriptorSet.
-static upb_flow_t upb_defbuilder_FileDescriptorSet_value(void *b,
- upb_fielddef *f,
- upb_value val) {
- (void)b;
- (void)val;
- switch(f->number) {
- case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM:
- return BEGIN_SUBMSG;
- }
- return UPB_CONTINUE;
-}
+static bool upb_symtab_add_defs(upb_symtab *s, upb_def **defs, int num_defs,
+ bool allow_redef, upb_status *status);
-static upb_flow_t upb_defbuilder_FileDescriptorSet_startsubmsg(
- void *_b, upb_fielddef *f, upb_handlers *h) {
+static void upb_defbuilder_FileDescriptorSet_onendmsg(void *_b,
+ upb_status *status) {
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_FIELDNUM:
- upb_defbuilder_register_FileDescriptorProto(b, h);
- return UPB_DELEGATE;
- }
- return UPB_SKIPSUBMSG;
+ if (upb_ok(status))
+ upb_symtab_add_defs(b->symtab, b->defs.defs, b->defs.len, false, status);
+ upb_defbuilder_free(b);
}
-static void upb_defbuilder_register_FileDescriptorSet(
- upb_defbuilder *b, upb_handlers *h) {
- static upb_handlerset handlers = {
- NULL, // startmsg
- NULL, // endmsg
- &upb_defbuilder_FileDescriptorSet_value,
- &upb_defbuilder_FileDescriptorSet_startsubmsg,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+static void upb_defbuilder_register_FileDescriptorSet(upb_handlers *h) {
+ upb_register_startend(h, NULL, upb_defbuilder_FileDescriptorSet_onendmsg);
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE__FIELDNUM,
+ GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE__FIELDTYPE);
+ upb_defbuilder_register_FileDescriptorProto(h);
+ upb_handlers_typed_pop(h);
+}
+void upb_defbuilder_reghandlers(upb_handlers *h) {
+ upb_defbuilder_register_FileDescriptorSet(h);
}
@@ -469,31 +442,33 @@ static upb_flow_t upb_enumdef_EnumValueDescriptorProto_startmsg(void *_b) {
return UPB_CONTINUE;
}
-static upb_flow_t upb_enumdef_EnumValueDescriptorProto_value(void *_b,
- upb_fielddef *f,
- upb_value val) {
+static upb_flow_t upb_enumdef_EnumValueDescriptorProto_name(void *_b,
+ upb_value fval,
+ upb_value val) {
+ (void)fval;
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_FIELDNUM:
- upb_string_unref(b->name);
- b->name = upb_string_getref(upb_value_getstr(val));
- b->saw_name = true;
- break;
- case GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_FIELDNUM:
- b->number = upb_value_getint32(val);
- b->saw_number = true;
- break;
- default:
- break;
- }
+ upb_string_unref(b->name);
+ b->name = upb_string_getref(upb_value_getstr(val));
+ b->saw_name = true;
return UPB_CONTINUE;
}
-static upb_flow_t upb_enumdef_EnumValueDescriptorProto_endmsg(void *_b) {
+static upb_flow_t upb_enumdef_EnumValueDescriptorProto_number(void *_b,
+ upb_value fval,
+ upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ b->number = upb_value_getint32(val);
+ b->saw_number = true;
+ return UPB_CONTINUE;
+}
+
+static void upb_enumdef_EnumValueDescriptorProto_endmsg(void *_b,
+ upb_status *status) {
upb_defbuilder *b = _b;
if(!b->saw_number || !b->saw_name) {
- upb_seterr(&b->status, UPB_ERROR, "Enum value missing name or number.");
- return UPB_BREAK;
+ upb_seterr(status, UPB_ERROR, "Enum value missing name or number.");
+ return;
}
upb_enumdef *e = upb_downcast_enumdef(upb_defbuilder_last(b));
if (upb_inttable_count(&e->iton) == 0) {
@@ -509,18 +484,19 @@ static upb_flow_t upb_enumdef_EnumValueDescriptorProto_endmsg(void *_b) {
// table. strtables can ref their keys, but the inttable doesn't know that
// the value is a string.
b->name = NULL;
- return UPB_CONTINUE;
}
-static void upb_enumdef_register_EnumValueDescriptorProto(upb_defbuilder *b,
- upb_handlers *h) {
- static upb_handlerset handlers = {
- &upb_enumdef_EnumValueDescriptorProto_startmsg,
- &upb_enumdef_EnumValueDescriptorProto_endmsg,
- &upb_enumdef_EnumValueDescriptorProto_value,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+static void upb_enumdef_register_EnumValueDescriptorProto(upb_handlers *h) {
+ upb_register_startend(h, upb_enumdef_EnumValueDescriptorProto_startmsg,
+ upb_enumdef_EnumValueDescriptorProto_endmsg);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME__FIELDNUM,
+ GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME__FIELDTYPE,
+ &upb_enumdef_EnumValueDescriptorProto_name, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER__FIELDNUM,
+ GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER__FIELDTYPE,
+ &upb_enumdef_EnumValueDescriptorProto_number, UPB_NO_VALUE);
}
// google.protobuf.EnumDescriptorProto.
@@ -534,61 +510,43 @@ static upb_flow_t upb_enumdef_EnumDescriptorProto_startmsg(void *_b) {
return UPB_CONTINUE;
}
-static upb_flow_t upb_enumdef_EnumDescriptorProto_endmsg(void *_b) {
+static void upb_enumdef_EnumDescriptorProto_endmsg(void *_b, upb_status *status) {
upb_defbuilder *b = _b;
upb_enumdef *e = upb_downcast_enumdef(upb_defbuilder_last(b));
if (upb_defbuilder_last((upb_defbuilder*)_b)->fqname == NULL) {
- upb_seterr(&b->status, UPB_ERROR, "Enum had no name.");
- return UPB_BREAK;
+ upb_seterr(status, UPB_ERROR, "Enum had no name.");
+ return;
}
if (upb_inttable_count(&e->iton) == 0) {
- upb_seterr(&b->status, UPB_ERROR, "Enum had no values.");
- return UPB_BREAK;
+ upb_seterr(status, UPB_ERROR, "Enum had no values.");
+ return;
}
- return UPB_CONTINUE;
}
-static upb_flow_t upb_enumdef_EnumDescriptorProto_value(void *_b,
- upb_fielddef *f,
- upb_value val) {
+static upb_flow_t upb_enumdef_EnumDescriptorProto_name(void *_b,
+ upb_value fval,
+ upb_value val) {
+ (void)fval;
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_FIELDNUM: {
- upb_enumdef *e = upb_downcast_enumdef(upb_defbuilder_last(b));
- upb_string_unref(e->base.fqname);
- e->base.fqname = upb_string_getref(upb_value_getstr(val));
- return UPB_CONTINUE;
- }
- case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM:
- return BEGIN_SUBMSG;
- default:
- return UPB_CONTINUE;
- }
+ upb_enumdef *e = upb_downcast_enumdef(upb_defbuilder_last(b));
+ upb_string_unref(e->base.fqname);
+ e->base.fqname = upb_string_getref(upb_value_getstr(val));
+ return UPB_CONTINUE;
}
-static upb_flow_t upb_enumdef_EnumDescriptorProto_startsubmsg(void *_b,
- upb_fielddef *f,
- upb_handlers *h) {
- upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_FIELDNUM:
- upb_enumdef_register_EnumValueDescriptorProto(b, h);
- return UPB_DELEGATE;
- default:
- return UPB_SKIPSUBMSG;
- }
-}
+static void upb_enumdef_register_EnumDescriptorProto(upb_handlers *h) {
+ upb_register_startend(h, &upb_enumdef_EnumDescriptorProto_startmsg,
+ &upb_enumdef_EnumDescriptorProto_endmsg);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME__FIELDNUM,
+ GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME__FIELDTYPE,
+ &upb_enumdef_EnumDescriptorProto_name, UPB_NO_VALUE);
-static void upb_enumdef_register_EnumDescriptorProto(upb_defbuilder *b,
- upb_handlers *h) {
- static upb_handlerset handlers = {
- &upb_enumdef_EnumDescriptorProto_startmsg,
- &upb_enumdef_EnumDescriptorProto_endmsg,
- &upb_enumdef_EnumDescriptorProto_value,
- &upb_enumdef_EnumDescriptorProto_startsubmsg,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE__FIELDNUM,
+ GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE__FIELDTYPE);
+ upb_enumdef_register_EnumValueDescriptorProto(h);
+ upb_handlers_typed_pop(h);
}
upb_enum_iter upb_enum_begin(upb_enumdef *e) {
@@ -650,7 +608,7 @@ static bool upb_fielddef_resolve(upb_fielddef *f, upb_def *def, upb_status *s) {
upb_string *str = upb_value_getstr(f->default_value);
assert(str); // Should point to either a real default or the empty string.
upb_enumdef *e = upb_downcast_enumdef(f->def);
- upb_enumval_t val;
+ upb_enumval_t val = 0;
if (str == upb_emptystring()) {
upb_value_setint32(&f->default_value, e->default_value);
} else {
@@ -776,7 +734,7 @@ static bool upb_fielddef_setdefault(upb_string *dstr, upb_value *d, int type) {
return success;
}
-static upb_flow_t upb_fielddef_endmsg(void *_b) {
+static void upb_fielddef_endmsg(void *_b, upb_status *status) {
upb_defbuilder *b = _b;
upb_fielddef *f = b->f;
// TODO: verify that all required fields were present.
@@ -795,53 +753,87 @@ static upb_flow_t upb_fielddef_endmsg(void *_b) {
if (!upb_fielddef_setdefault(dstr, &f->default_value, f->type)) {
// We don't worry too much about giving a great error message since the
// compiler should have ensured this was correct.
- upb_seterr(&b->status, UPB_ERROR, "Error converting default value.");
- return UPB_BREAK;
+ upb_seterr(status, UPB_ERROR, "Error converting default value.");
+ return;
}
+}
+
+static upb_flow_t upb_fielddef_ontype(void *_b, upb_value fval, upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ b->f->type = upb_value_getint32(val);
return UPB_CONTINUE;
}
-static upb_flow_t upb_fielddef_value(void *_b, upb_fielddef *f, upb_value val) {
+static upb_flow_t upb_fielddef_onlabel(void *_b, upb_value fval, upb_value val) {
+ (void)fval;
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIELDNUM:
- b->f->type = upb_value_getint32(val);
- break;
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_FIELDNUM:
- b->f->label = upb_value_getint32(val);
- break;
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_FIELDNUM:
- b->f->number = upb_value_getint32(val);
- break;
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_FIELDNUM:
- upb_string_unref(b->f->name);
- b->f->name = upb_string_getref(upb_value_getstr(val));
- break;
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_FIELDNUM: {
- upb_def_unref(b->f->def);
- b->f->def = UPB_UPCAST(upb_unresolveddef_new(upb_value_getstr(val)));
- b->f->owned = true;
- break;
- }
- case GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_FIELDNUM:
- // Have to convert from string to the correct type, but we might not know
- // the type yet.
- upb_string_unref(b->default_string);
- b->default_string = upb_string_getref(upb_value_getstr(val));
- break;
- }
+ b->f->label = upb_value_getint32(val);
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_fielddef_onnumber(void *_b, upb_value fval, upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ b->f->number = upb_value_getint32(val);
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_fielddef_onname(void *_b, upb_value fval, upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ upb_string_unref(b->f->name);
+ b->f->name = upb_string_getref(upb_value_getstr(val));
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_fielddef_ontypename(void *_b, upb_value fval,
+ upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ upb_def_unref(b->f->def);
+ b->f->def = UPB_UPCAST(upb_unresolveddef_new(upb_value_getstr(val)));
+ b->f->owned = true;
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_fielddef_ondefaultval(void *_b, upb_value fval,
+ upb_value val) {
+ (void)fval;
+ upb_defbuilder *b = _b;
+ // Have to convert from string to the correct type, but we might not know the
+ // type yet.
+ upb_string_unref(b->default_string);
+ b->default_string = upb_string_getref(upb_value_getstr(val));
return UPB_CONTINUE;
}
-static void upb_fielddef_register_FieldDescriptorProto(upb_defbuilder *b,
- upb_handlers *h) {
- static upb_handlerset handlers = {
- &upb_fielddef_startmsg,
- &upb_fielddef_endmsg,
- &upb_fielddef_value,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+static void upb_fielddef_register_FieldDescriptorProto(upb_handlers *h) {
+ upb_register_startend(h, upb_fielddef_startmsg, upb_fielddef_endmsg);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE__FIELDTYPE,
+ &upb_fielddef_ontype, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL__FIELDTYPE,
+ &upb_fielddef_onlabel, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER__FIELDTYPE,
+ &upb_fielddef_onnumber, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME__FIELDTYPE,
+ &upb_fielddef_onname, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME__FIELDTYPE,
+ &upb_fielddef_ontypename, UPB_NO_VALUE);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE__FIELDNUM,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE__FIELDTYPE,
+ &upb_fielddef_ondefaultval, UPB_NO_VALUE);
}
@@ -874,12 +866,12 @@ static upb_flow_t upb_msgdef_startmsg(void *_b) {
return UPB_CONTINUE;
}
-static upb_flow_t upb_msgdef_endmsg(void *_b) {
+static void upb_msgdef_endmsg(void *_b, upb_status *status) {
upb_defbuilder *b = _b;
upb_msgdef *m = upb_defbuilder_top(b);
if(!m->base.fqname) {
- upb_seterr(&b->status, UPB_ERROR, "Encountered message with no name.");
- return UPB_BREAK;
+ upb_seterr(status, UPB_ERROR, "Encountered message with no name.");
+ return;
}
upb_inttable_compact(&m->itof);
@@ -944,58 +936,44 @@ static upb_flow_t upb_msgdef_endmsg(void *_b) {
}
upb_defbuilder_endcontainer(b);
- return UPB_CONTINUE;
}
-static upb_flow_t upb_msgdef_value(void *_b, upb_fielddef *f, upb_value val) {
+static upb_flow_t upb_msgdef_onname(void *_b, upb_value fval, upb_value val) {
+ (void)fval;
upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_FIELDNUM: {
- assert(val.type == UPB_TYPE(STRING));
- upb_msgdef *m = upb_defbuilder_top(b);
- upb_string_unref(m->base.fqname);
- m->base.fqname = upb_string_getref(upb_value_getstr(val));
- upb_defbuilder_setscopename(b, upb_value_getstr(val));
- return UPB_CONTINUE;
- }
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM:
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_FIELDNUM:
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_FIELDNUM:
- return BEGIN_SUBMSG;
- default:
- // TODO: extensions.
- return UPB_CONTINUE;
- }
+ assert(val.type == UPB_TYPE(STRING));
+ upb_msgdef *m = upb_defbuilder_top(b);
+ upb_string_unref(m->base.fqname);
+ m->base.fqname = upb_string_getref(upb_value_getstr(val));
+ upb_defbuilder_setscopename(b, upb_value_getstr(val));
+ return UPB_CONTINUE;
}
-static upb_flow_t upb_msgdef_startsubmsg(void *_b, upb_fielddef *f,
- upb_handlers *h) {
- upb_defbuilder *b = _b;
- switch(f->number) {
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_FIELDNUM:
- upb_fielddef_register_FieldDescriptorProto(b, h);
- return UPB_DELEGATE;
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_FIELDNUM:
- upb_msgdef_register_DescriptorProto(b, h);
- return UPB_DELEGATE;
- case GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_FIELDNUM:
- upb_enumdef_register_EnumDescriptorProto(b, h);
- return UPB_DELEGATE;
- default:
- return UPB_SKIPSUBMSG;
- }
-}
+static void upb_msgdef_register_DescriptorProto(upb_handlers *h) {
+ upb_register_startend(h, &upb_msgdef_startmsg, &upb_msgdef_endmsg);
+ upb_register_typed_value(h,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME__FIELDNUM,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME__FIELDTYPE,
+ &upb_msgdef_onname, UPB_NO_VALUE);
+
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD__FIELDNUM,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD__FIELDTYPE);
+ upb_fielddef_register_FieldDescriptorProto(h);
+ upb_handlers_typed_pop(h);
+
+ // DescriptorProto is self-recursive, so we must link the definition.
+ upb_handlers_typed_link(h,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE__FIELDNUM,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE__FIELDTYPE, 0);
-static void upb_msgdef_register_DescriptorProto(upb_defbuilder *b,
- upb_handlers *h) {
- static upb_handlerset handlers = {
- &upb_msgdef_startmsg,
- &upb_msgdef_endmsg,
- &upb_msgdef_value,
- &upb_msgdef_startsubmsg,
- };
- upb_register_handlerset(h, &handlers);
- upb_set_handler_closure(h, b, &b->status);
+ upb_handlers_typed_push(h,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE__FIELDNUM,
+ GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE__FIELDTYPE);
+ upb_enumdef_register_EnumDescriptorProto(h);
+ upb_handlers_typed_pop(h);
+
+ // TODO: extensions.
}
static void upb_msgdef_free(upb_msgdef *m)
@@ -1185,8 +1163,8 @@ bool upb_resolverefs(upb_strtable *tmptab, upb_strtable *symtab,
// indicating whether the new defs can overwrite existing defs in the symtab,
// attempts to add the given defs to the symtab. The whole operation either
// succeeds or fails. Ownership of "defs" and "exts" is taken.
-bool upb_symtab_add_defs(upb_symtab *s, upb_def **defs, int num_defs,
- bool allow_redef, upb_status *status)
+static bool upb_symtab_add_defs(upb_symtab *s, upb_def **defs, int num_defs,
+ bool allow_redef, upb_status *status)
{
upb_rwlock_wrlock(&s->lock);
@@ -1325,232 +1303,3 @@ upb_def *upb_symtab_resolve(upb_symtab *s, upb_string *base, upb_string *symbol)
upb_rwlock_unlock(&s->lock);
return ret;
}
-
-void upb_symtab_addfds(upb_symtab *s, upb_src *src, upb_status *status)
-{
- upb_defbuilder b;
- upb_defbuilder_init(&b);
- upb_handlers handlers;
- upb_handlers_init(&handlers);
- upb_defbuilder_register_FileDescriptorSet(&b, &handlers);
- upb_src_sethandlers(src, &handlers);
- upb_src_run(src, status);
- if (upb_ok(status))
- upb_symtab_add_defs(s, b.defs.defs, b.defs.len, false, status);
- upb_defbuilder_uninit(&b);
- upb_handlers_uninit(&handlers);
-}
-
-
-/* upb_baredecoder ************************************************************/
-
-// upb_baredecoder is a upb_src that can parse a subset of the protocol buffer
-// binary format. It is only used for bootstrapping. It can parse without
-// having a upb_msgdef, which is why it is useful for bootstrapping the first
-// msgdef. On the downside, it does not support:
-//
-// * having its input span multiple upb_strings.
-// * reading any field of the returned upb_fielddef's except f->number.
-// * keeping a pointer to the upb_fielddef* and reading it later (the same
-// upb_fielddef is reused over and over).
-// * detecting errors in the input (we trust that our input is known-good).
-// * skipping the rest of the submessage (UPB_SKIPSUBMSG).
-//
-// It also does not support any of the follow protobuf features:
-// * packed fields.
-// * groups.
-// * zig-zag-encoded types like sint32 and sint64.
-//
-// Since it cannot tell the difference between submessages and strings, it
-// always reports them as strings first, but if the value callback returns
-// UPB_TREAT_AS_SUBMSG this signals to the baredecoder that it should be
-// treated like a submessage instead.
-//
-// TODO: for bootstrapping we should define a slightly different wire format
-// that includes enough information to know the precise integer types and
-// that distinguishes between strings and submessages. This will allow
-// us to get rid of the UPB_TREAT_AS_SUBMSG hack. It will also allow us
-// to get rid of the upb_value_setraw() scheme, which would be more
-// complicated to support on big-endian machines.
-
-typedef struct {
- upb_src src;
- upb_string *input;
- upb_strlen_t offset;
- upb_dispatcher dispatcher;
-} upb_baredecoder;
-
-static uint64_t upb_baredecoder_readv64(upb_baredecoder *d)
-{
- const uint8_t *start = (uint8_t*)upb_string_getrobuf(d->input) + d->offset;
- const uint8_t *buf = start;
- uint8_t last = 0x80;
- uint64_t val = 0;
- for(int bitpos = 0; (last & 0x80); buf++, bitpos += 7)
- val |= ((uint64_t)((last = *buf) & 0x7F)) << bitpos;
- d->offset += buf - start;
- return val;
-}
-
-static uint32_t upb_baredecoder_readv32(upb_baredecoder *d)
-{
- return (uint32_t)upb_baredecoder_readv64(d); // Truncate.
-}
-
-static uint64_t upb_baredecoder_readf64(upb_baredecoder *d)
-{
- uint64_t val;
- memcpy(&val, upb_string_getrobuf(d->input) + d->offset, 8);
- d->offset += 8;
- return val;
-}
-
-static uint32_t upb_baredecoder_readf32(upb_baredecoder *d)
-{
- uint32_t val;
- memcpy(&val, upb_string_getrobuf(d->input) + d->offset, 4);
- d->offset += 4;
- return val;
-}
-
-static void upb_baredecoder_sethandlers(upb_src *src, upb_handlers *handlers) {
- upb_baredecoder *d = (upb_baredecoder*)src;
- upb_dispatcher_reset(&d->dispatcher, handlers, false);
-}
-
-static void upb_baredecoder_run(upb_src *src, upb_status *status) {
- upb_baredecoder *d = (upb_baredecoder*)src;
- assert(!upb_handlers_isempty(&d->dispatcher.top->handlers));
- upb_string *str = NULL;
- upb_strlen_t stack[UPB_MAX_NESTING] = {UPB_STRLEN_MAX};
- upb_strlen_t *top = &stack[0];
- d->offset = 0;
-
-#define CHECK(x) if (x != UPB_CONTINUE && x != BEGIN_SUBMSG) goto err;
-
- CHECK(upb_dispatch_startmsg(&d->dispatcher));
- while(d->offset < upb_string_len(d->input)) {
- uint32_t key = upb_baredecoder_readv64(d);
- upb_fielddef f;
- f.number = key >> 3;
- upb_wire_type_t wt = key & 0x7;
- if(wt == UPB_WIRE_TYPE_DELIMITED) {
- uint32_t delim_len = upb_baredecoder_readv32(d);
- // We don't know if it's a string or a submessage; deliver first as
- // string.
- upb_string_recycle(&str);
- upb_string_substr(str, d->input, d->offset, delim_len);
- upb_value v;
- upb_value_setstr(&v, str);
- upb_flow_t ret = upb_dispatch_value(&d->dispatcher, &f, v);
- CHECK(ret);
- if(ret == BEGIN_SUBMSG) {
- // Should deliver as a submessage instead.
- CHECK(upb_dispatch_startsubmsg(&d->dispatcher, &f));
- *(++top) = d->offset + delim_len;
- } else {
- d->offset += delim_len;
- }
- } else {
- upb_value v;
- switch(wt) {
- case UPB_WIRE_TYPE_VARINT:
- upb_value_setraw(&v, upb_baredecoder_readv64(d));
- break;
- case UPB_WIRE_TYPE_64BIT:
- upb_value_setraw(&v, upb_baredecoder_readf64(d));
- break;
- case UPB_WIRE_TYPE_32BIT:
- upb_value_setraw(&v, upb_baredecoder_readf32(d));
- break;
- default:
- assert(false);
- abort();
- }
- CHECK(upb_dispatch_value(&d->dispatcher, &f, v));
- }
- // Detect end-of-submessage.
- while(d->offset >= *top) {
- CHECK(upb_dispatch_endsubmsg(&d->dispatcher, &f));
- d->offset = *(top--);
- }
- }
- CHECK(upb_dispatch_endmsg(&d->dispatcher));
- upb_string_unref(str);
- return;
-
-err:
- upb_copyerr(status, d->dispatcher.top->handlers.status);
- upb_string_unref(str);
-}
-
-static upb_baredecoder *upb_baredecoder_new(upb_string *str) {
- static upb_src_vtbl vtbl = {
- &upb_baredecoder_sethandlers,
- &upb_baredecoder_run,
- };
- upb_baredecoder *d = malloc(sizeof(*d));
- upb_src_init(&d->src, &vtbl);
- d->input = upb_string_getref(str);
- d->offset = 0;
- upb_dispatcher_init(&d->dispatcher);
- return d;
-}
-
-static void upb_baredecoder_free(upb_baredecoder *d) {
- upb_string_unref(d->input);
- free(d);
-}
-
-static upb_src *upb_baredecoder_src(upb_baredecoder *d) {
- return &d->src;
-}
-
-static upb_symtab *descriptor_symtab = NULL;
-
-static void upb_free_descriptor_symtab() {
- if (descriptor_symtab) {
- // There should be no way for anyone to acquire a ref on this symtab.
- assert(upb_atomic_only(&descriptor_symtab->refcount));
- _upb_symtab_free(descriptor_symtab);
- descriptor_symtab = NULL;
- }
-}
-
-upb_def *upb_getdescriptordef(upb_string *str) {
- // TODO: add locking.
- if (descriptor_symtab == NULL) {
- descriptor_symtab = upb_symtab_new();
-
- static upb_string descriptor_str =
- UPB_STATIC_STRING_ARRAY(descriptor_pb);
- upb_baredecoder *decoder = upb_baredecoder_new(&descriptor_str);
- upb_status status = UPB_STATUS_INIT;
- upb_symtab_addfds(descriptor_symtab, upb_baredecoder_src(decoder), &status);
- upb_baredecoder_free(decoder);
-
- if(!upb_ok(&status)) {
- // upb itself is corrupt.
- upb_printerr(&status);
- upb_clearerr(&status);
- abort();
- }
- upb_status_uninit(&status);
-
- // As a sanity check, make sure that FileDescriptorSet was loaded.
- upb_msgdef *def = upb_getfdsdef();
- if (!def) {
- // upb itself is corrupt.
- abort();
- }
- upb_msgdef_unref(def); // The symtab already holds a ref on it.
- atexit(upb_free_descriptor_symtab);
- }
- return upb_symtab_resolve(
- descriptor_symtab, UPB_STRLIT("google.protobuf"), str);
-}
-
-upb_msgdef *upb_getfdsdef() {
- return upb_downcast_msgdef(
- upb_getdescriptordef(UPB_STRLIT("FileDescriptorSet")));
-}
diff --git a/src/upb_def.h b/src/upb_def.h
index 4a2bcbd..9950c86 100644
--- a/src/upb_def.h
+++ b/src/upb_def.h
@@ -28,7 +28,6 @@
#define UPB_DEF_H_
#include "upb_atomic.h"
-#include "upb_stream.h"
#include "upb_table.h"
#ifdef __cplusplus
@@ -90,7 +89,7 @@ INLINE void upb_def_unref(upb_def *def) {
// in the sense that it derives from upb_def. It cannot stand on its own; it
// is either a field of a upb_msgdef or contained inside a upb_extensiondef.
// It is also reference-counted.
-typedef struct _upb_fielddef {
+struct _upb_fielddef {
uint8_t type;
uint8_t label;
// True if we own a ref on "def" (above). This is true unless this edge is
@@ -111,11 +110,14 @@ typedef struct _upb_fielddef {
// For the case of an enum or a submessage, points to the def for that type.
upb_def *def;
upb_atomic_refcount_t refcount;
-} upb_fielddef;
+};
// A variety of tests about the type of a field.
+INLINE bool upb_issubmsgtype(upb_fieldtype_t type) {
+ return type == UPB_TYPE(GROUP) || type == UPB_TYPE(MESSAGE);
+}
INLINE bool upb_issubmsg(upb_fielddef *f) {
- return f->type == UPB_TYPE(GROUP) || f->type == UPB_TYPE(MESSAGE);
+ return upb_issubmsgtype(f->type);
}
INLINE bool upb_isstring(upb_fielddef *f) {
return f->type == UPB_TYPE(STRING) || f->type == UPB_TYPE(BYTES);
@@ -225,6 +227,7 @@ INLINE upb_fielddef *upb_msg_iter_field(upb_msg_iter iter) {
return ent->f;
}
+
/* upb_enumdef ****************************************************************/
typedef int32_t upb_enumval_t;
@@ -274,8 +277,8 @@ INLINE int32_t upb_enum_iter_number(upb_enum_iter iter) {
/* upb_symtab *****************************************************************/
// A SymbolTable is where upb_defs live. It is empty when first constructed.
-// Clients add definitions to the symtab by supplying unserialized or
-// serialized descriptors (as defined in descriptor.proto).
+// Clients add definitions to the symtab by supplying descriptors (as defined
+// in descriptor.proto) via the upb_stream interface.
struct _upb_symtab {
upb_atomic_refcount_t refcount;
upb_rwlock_t lock; // Protects all members except the refcount.
@@ -284,7 +287,7 @@ struct _upb_symtab {
};
typedef struct _upb_symtab upb_symtab;
-// Initializes a upb_symtab. Contexts are not freed explicitly, but unref'd
+// Initializes a upb_symtab. Symtabs are not freed explicitly, but unref'd
// when the caller is done with them.
upb_symtab *upb_symtab_new(void);
void _upb_symtab_free(upb_symtab *s); // Must not be called directly!
@@ -316,33 +319,22 @@ upb_def *upb_symtab_lookup(upb_symtab *s, upb_string *sym);
// returned, otherwise only defs of the required type are returned.
upb_def **upb_symtab_getdefs(upb_symtab *s, int *count, upb_deftype_t type);
-// "fds" is a upb_src that will yield data from the
-// google.protobuf.FileDescriptorSet message type. It is not necessary that
-// the upb_def for FileDescriptorSet came from this symtab, but it must be
-// compatible with the official descriptor.proto, as published by Google.
-//
-// upb_symtab_addfds() adds all the definitions from the given
-// FileDescriptorSet and adds them to the symtab. status indicates whether the
-// operation was successful or not, and the error message (if any).
+// upb_defbuilder: For adding defs to the symtab.
+// You allocate the defbuilder, which can handle a single descriptor.
+// It will be freed automatically when the parse completes.
+struct _upb_defbuilder;
+typedef struct _upb_defbuilder upb_defbuilder;
+struct _upb_handlers;
+
+// Allocates a new defbuilder that will add defs to the given symtab.
+upb_defbuilder *upb_defbuilder_new(upb_symtab *s);
+
+// Registers handlers that will operate on a defbuilder to add the defs
+// to the defbuilder's symtab. Will free itself when the parse finishes.
//
// TODO: should this allow redefinition? Either is possible, but which is
// more useful? Maybe it should be an option.
-void upb_symtab_addfds(upb_symtab *s, upb_src *desc, upb_status *status);
-
-// Returns a def corresponding to the given name, from descriptor.proto.
-// upb internally bootstraps the defs in descriptor.proto, since they are
-// necessary for loading other descriptors. The caller owns a ref on the
-// returned def (which is NULL if no such def exists in descriptor.proto).
-//
-// The name should *not* be qualified by the package, to promote
-// interoperability between the internal and external releases of Protocol
-// Buffers (inside Google, these are in the "proto2" package, externally they
-// are in "google.protobuf".
-upb_def *upb_getdescriptordef(upb_string *str);
-
-// A convenience method for getting the upb_def for FileDescriptorProto.
-// Return should never be NULL.
-upb_msgdef *upb_getfdsdef();
+void upb_defbuilder_reghandlers(struct _upb_handlers *h);
/* upb_def casts **************************************************************/
diff --git a/src/upb_encoder.h b/src/upb_encoder.h
index e879b0b..d8d4b4f 100644
--- a/src/upb_encoder.h
+++ b/src/upb_encoder.h
@@ -14,7 +14,7 @@
#define UPB_ENCODER_H_
#include "upb.h"
-#include "upb_srcsink.h"
+#include "upb_stream.h"
#ifdef __cplusplus
extern "C" {
diff --git a/src/upb_glue.c b/src/upb_glue.c
index 86022d8..8194d4a 100644
--- a/src/upb_glue.c
+++ b/src/upb_glue.c
@@ -16,25 +16,18 @@ void upb_strtomsg(upb_string *str, upb_msg *msg, upb_msgdef *md,
upb_stringsrc_init(&strsrc);
upb_stringsrc_reset(&strsrc, str);
- upb_decoder d;
- upb_decoder_init(&d, md);
- upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc));
- upb_src *src = upb_decoder_src(&d);
-
- upb_msgpopulator p;
- upb_msgpopulator_init(&p);
- upb_msgpopulator_reset(&p, msg, md);
-
upb_handlers h;
- upb_handlers_init(&h);
- upb_msgpopulator_register_handlers(&p, &h);
- upb_src_sethandlers(src, &h);
+ upb_handlers_init(&h, md);
+ upb_msg_regdhandlers(&h);
+
+ upb_decoder d;
+ upb_decoder_init(&d, &h);
+ upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc), msg);
- upb_src_run(src, status);
+ upb_decoder_decode(&d, status);
upb_stringsrc_uninit(&strsrc);
upb_decoder_uninit(&d);
- upb_msgpopulator_uninit(&p);
upb_handlers_uninit(&h);
}
@@ -46,11 +39,12 @@ void upb_msgtotext(upb_string *str, upb_msg *msg, upb_msgdef *md,
upb_textprinter *p = upb_textprinter_new();
upb_handlers h;
- upb_handlers_init(&h);
- upb_textprinter_reset(p, &h, upb_stringsink_bytesink(&strsink), single_line);
+ upb_handlers_init(&h, md);
+ upb_textprinter_reghandlers(&h);
+ upb_textprinter_reset(p, upb_stringsink_bytesink(&strsink), single_line);
upb_status status = UPB_STATUS_INIT;
- upb_msg_runhandlers(msg, md, &h, &status);
+ upb_msg_runhandlers(msg, md, &h, p, &status);
// None of {upb_msg_runhandlers, upb_textprinter, upb_stringsink} should be
// capable of returning an error.
assert(upb_ok(&status));
@@ -66,13 +60,18 @@ void upb_parsedesc(upb_symtab *symtab, upb_string *str, upb_status *status) {
upb_stringsrc_init(&strsrc);
upb_stringsrc_reset(&strsrc, str);
+ upb_handlers h;
+ upb_handlers_init(&h, NULL);
+ upb_defbuilder_reghandlers(&h);
+
upb_decoder d;
- upb_msgdef *fds_msgdef = upb_getfdsdef();
- upb_decoder_init(&d, fds_msgdef);
- upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc));
+ upb_decoder_init(&d, &h);
+ upb_defbuilder *b = upb_defbuilder_new(symtab);
+ upb_decoder_reset(&d, upb_stringsrc_bytesrc(&strsrc), b);
- upb_symtab_addfds(symtab, upb_decoder_src(&d), status);
+ upb_decoder_decode(&d, status);
+
+ upb_handlers_uninit(&h);
upb_stringsrc_uninit(&strsrc);
upb_decoder_uninit(&d);
- upb_def_unref(UPB_UPCAST(fds_msgdef));
}
diff --git a/src/upb_msg.c b/src/upb_msg.c
index a3fd825..a9167e8 100644
--- a/src/upb_msg.c
+++ b/src/upb_msg.c
@@ -7,8 +7,6 @@
*/
#include "upb_msg.h"
-#include "upb_decoder.h"
-#include "upb_strstream.h"
static uint32_t upb_round_up_pow2(uint32_t v) {
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
@@ -181,75 +179,66 @@ upb_value upb_msg_get(upb_msg *msg, upb_fielddef *f) {
}
static upb_flow_t upb_msg_dispatch(upb_msg *msg, upb_msgdef *md,
- upb_dispatcher *d, upb_status *s);
+ upb_dispatcher *d);
static upb_flow_t upb_msg_pushval(upb_value val, upb_fielddef *f,
- upb_dispatcher *d, upb_status *s) {
+ upb_dispatcher *d, upb_handlers_fieldent *hf) {
#define CHECK_FLOW(x) do { \
- flow = x; if (flow != UPB_CONTINUE) return flow; \
+ upb_flow_t flow = x; if (flow != UPB_CONTINUE) return flow; \
} while(0)
// For when a SKIP can be implemented just through an early return.
#define CHECK_FLOW_LOCAL(x) do { \
- flow = x; \
+ upb_flow_t flow = x; \
if (flow != UPB_CONTINUE) { \
if (flow == UPB_SKIPSUBMSG) flow = UPB_CONTINUE; \
- goto end; \
+ return flow; \
} \
} while (0)
- upb_flow_t flow;
if (upb_issubmsg(f)) {
upb_msg *msg = upb_value_getmsg(val);
- CHECK_FLOW_LOCAL(upb_dispatch_startsubmsg(d, f));
- CHECK_FLOW_LOCAL(upb_msg_dispatch(msg, upb_downcast_msgdef(f->def), d, s));
- CHECK_FLOW(upb_dispatch_endsubmsg(d, f));
+ CHECK_FLOW_LOCAL(upb_dispatch_startsubmsg(d, hf, 0));
+ CHECK_FLOW_LOCAL(upb_msg_dispatch(msg, upb_downcast_msgdef(f->def), d));
+ CHECK_FLOW(upb_dispatch_endsubmsg(d));
} else {
- CHECK_FLOW(upb_dispatch_value(d, f, val));
+ CHECK_FLOW(upb_dispatch_value(d, hf, val));
}
-
-end:
- return flow;
+ return UPB_CONTINUE;
}
static upb_flow_t upb_msg_dispatch(upb_msg *msg, upb_msgdef *md,
- upb_dispatcher *d, upb_status *s) {
+ upb_dispatcher *d) {
upb_msg_iter i;
- upb_flow_t flow;
for(i = upb_msg_begin(md); !upb_msg_done(i); i = upb_msg_next(md, i)) {
upb_fielddef *f = upb_msg_iter_field(i);
if (!upb_msg_has(msg, f)) continue;
+ upb_handlers_fieldent *hf = upb_dispatcher_lookup(d, f->number);
+ if (!hf) continue;
upb_value val = upb_msg_get(msg, f);
if (upb_isarray(f)) {
upb_array *arr = upb_value_getarr(val);
for (uint32_t j = 0; j < upb_array_len(arr); ++j) {
- CHECK_FLOW_LOCAL(upb_msg_pushval(upb_array_get(arr, f, j), f, d, s));
+ CHECK_FLOW_LOCAL(upb_msg_pushval(upb_array_get(arr, f, j), f, d, hf));
}
} else {
- CHECK_FLOW_LOCAL(upb_msg_pushval(val, f, d, s));
+ CHECK_FLOW_LOCAL(upb_msg_pushval(val, f, d, hf));
}
}
return UPB_CONTINUE;
-
-end:
- // Need to copy/massage the error.
- upb_copyerr(s, d->top->handlers.status);
- if (upb_ok(s)) {
- upb_seterr(s, UPB_ERROR, "Callback returned UPB_BREAK");
- }
- return flow;
#undef CHECK_FLOW
#undef CHECK_FLOW_LOCAL
}
void upb_msg_runhandlers(upb_msg *msg, upb_msgdef *md, upb_handlers *h,
- upb_status *status) {
+ void *closure, upb_status *status) {
upb_dispatcher d;
- upb_dispatcher_init(&d);
- upb_dispatcher_reset(&d, h, true);
+ upb_dispatcher_init(&d, h, 0);
- if (upb_dispatch_startmsg(&d) != UPB_CONTINUE) return;
- if (upb_msg_dispatch(msg, md, &d, status) != UPB_CONTINUE) return;
- if (upb_dispatch_endmsg(&d) != UPB_CONTINUE) return;
+ upb_dispatch_startmsg(&d, closure);
+ upb_msg_dispatch(msg, md, &d);
+ upb_dispatch_endmsg(&d, status);
+
+ upb_dispatcher_uninit(&d);
}
static upb_valueptr upb_msg_getappendptr(upb_msg *msg, upb_fielddef *f) {
@@ -283,7 +272,7 @@ static void upb_msg_appendval(upb_msg *msg, upb_fielddef *f, upb_value val) {
// If you were using this to copy one upb_msg to another this would
// allocate string objects whereas a upb_string_getref could have avoided
// those allocations completely; if this is an issue, we could make it an
- // option of the upb_msgpopulator which behavior is desired.
+ // option of the upb_msgsink which behavior is desired.
upb_string *src = upb_value_getstr(val);
upb_string_recycle(p.str);
upb_string_substr(*p.str, src, 0, upb_string_len(src));
@@ -303,59 +292,28 @@ upb_msg *upb_msg_appendmsg(upb_msg *msg, upb_fielddef *f, upb_msgdef *msgdef) {
}
-/* upb_msgpopulator ***********************************************************/
-
-void upb_msgpopulator_init(upb_msgpopulator *p) {
- upb_status_init(&p->status);
-}
-
-void upb_msgpopulator_reset(upb_msgpopulator *p, upb_msg *m, upb_msgdef *md) {
- p->top = p->stack;
- p->limit = p->stack + sizeof(p->stack);
- p->top->msg = m;
- p->top->msgdef = md;
-}
-
-void upb_msgpopulator_uninit(upb_msgpopulator *p) {
- upb_status_uninit(&p->status);
-}
+/* upb_msg dynhandlers *******************************************************/
-static upb_flow_t upb_msgpopulator_value(void *_p, upb_fielddef *f, upb_value val) {
- upb_msgpopulator *p = _p;
- upb_msg_appendval(p->top->msg, f, val);
+static upb_flow_t upb_dmsgsink_value(void *_m, upb_value fval, upb_value val) {
+ upb_msg *m = _m;
+ upb_fielddef *f = upb_value_getfielddef(fval);
+ upb_msg_appendval(m, f, val);
return UPB_CONTINUE;
}
-static upb_flow_t upb_msgpopulator_startsubmsg(void *_p, upb_fielddef *f,
- upb_handlers *delegate_to) {
- upb_msgpopulator *p = _p;
- (void)delegate_to;
- upb_msg *oldmsg = p->top->msg;
- if (++p->top == p->limit) {
- upb_seterr(&p->status, UPB_ERROR, "Exceeded maximum nesting");
- return UPB_BREAK;
- }
+static upb_sflow_t upb_dmsgsink_startsubmsg(void *_m, upb_value fval) {
+ upb_msg *m = _m;
+ upb_fielddef *f = upb_value_getfielddef(fval);
upb_msgdef *msgdef = upb_downcast_msgdef(f->def);
- p->top->msgdef = msgdef;
- p->top->msg = upb_msg_appendmsg(oldmsg, f, msgdef);
- return UPB_CONTINUE;
-}
-
-static upb_flow_t upb_msgpopulator_endsubmsg(void *_p, upb_fielddef *f) {
- (void)f;
- upb_msgpopulator *p = _p;
- --p->top;
- return UPB_CONTINUE;
+ return UPB_CONTINUE_WITH(upb_msg_appendmsg(m, f, msgdef));
}
-void upb_msgpopulator_register_handlers(upb_msgpopulator *p, upb_handlers *h) {
- static upb_handlerset handlerset = {
- NULL, // startmsg
- NULL, // endmsg
- &upb_msgpopulator_value,
- &upb_msgpopulator_startsubmsg,
- &upb_msgpopulator_endsubmsg,
- };
- upb_register_handlerset(h, &handlerset);
- upb_set_handler_closure(h, p, &p->status);
+void upb_msg_regdhandlers(upb_handlers *h) {
+ upb_register_all(h,
+ NULL, // startmsg
+ NULL, // endmsg
+ &upb_dmsgsink_value,
+ &upb_dmsgsink_startsubmsg,
+ NULL, // endsubmsg
+ NULL); // unknown
}
diff --git a/src/upb_msg.h b/src/upb_msg.h
index fd5750f..4895c4b 100644
--- a/src/upb_msg.h
+++ b/src/upb_msg.h
@@ -17,8 +17,7 @@
#ifndef UPB_MSG_H
#define UPB_MSG_H
-#include "upb.h"
-#include "upb_def.h"
+#include "upb_stream.h"
#include <stdlib.h>
#ifdef __cplusplus
@@ -274,26 +273,16 @@ INLINE void upb_msg_clear(upb_msg *msg, upb_msgdef *md) {
memset(msg->data, 0, md->set_flags_bytes);
}
-// A non-resumable upb_src that pushes the current contents of the message to
-// the given handlers.
+// Registers handlers for populating a msg for the given upb_msgdef.
+// The upb_msg itself must be passed as the param to the src.
+void upb_msg_reghandlers(upb_handlers *h, upb_msgdef *md);
+
+// Registers handlers that are suitable for populating a msg of *any*
+// upb_msgdef ("dynamic" handlers). May be slower than upb_msg_reghandlers().
+void upb_msg_regdhandlers(upb_handlers *h);
+
void upb_msg_runhandlers(upb_msg *msg, upb_msgdef *md, upb_handlers *h,
- upb_status *status);
-
-typedef struct {
- upb_msg *msg;
- upb_msgdef *msgdef;
-} upb_msgpopulator_frame;
-
-typedef struct {
- upb_msgpopulator_frame *top, *limit;
- upb_status status;
- upb_msgpopulator_frame stack[UPB_MAX_NESTING];
-} upb_msgpopulator;
-
-void upb_msgpopulator_init(upb_msgpopulator *p);
-void upb_msgpopulator_uninit(upb_msgpopulator *p);
-void upb_msgpopulator_reset(upb_msgpopulator *p, upb_msg *m, upb_msgdef *md);
-void upb_msgpopulator_register_handlers(upb_msgpopulator *p, upb_handlers *h);
+ void *closure, upb_status *status);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/upb_stdio.c b/src/upb_stdio.c
index 8857677..b4f2fce 100644
--- a/src/upb_stdio.c
+++ b/src/upb_stdio.c
@@ -85,7 +85,6 @@ upb_stdio *upb_stdio_new() {
};
static upb_bytesink_vtbl bytesink_vtbl = {
- NULL,
upb_stdio_putstr,
upb_stdio_vprintf
};
diff --git a/src/upb_stream.c b/src/upb_stream.c
new file mode 100644
index 0000000..3634d5d
--- /dev/null
+++ b/src/upb_stream.c
@@ -0,0 +1,328 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2011 Joshua Haberman. See LICENSE for details.
+ */
+
+#include <stdlib.h>
+#include "upb_stream.h"
+
+
+/* upb_handlers ***************************************************************/
+
+static upb_flow_t upb_startmsg_nop(void *closure) {
+ (void)closure;
+ return UPB_CONTINUE;
+}
+
+static void upb_endmsg_nop(void *closure, upb_status *status) {
+ (void)closure;
+ (void)status;
+}
+
+static upb_flow_t upb_value_nop(void *closure, upb_value fval, upb_value val) {
+ (void)closure;
+ (void)fval;
+ (void)val;
+ return UPB_CONTINUE;
+}
+
+static upb_sflow_t upb_startsubmsg_nop(void *closure, upb_value fval) {
+ (void)fval;
+ return UPB_CONTINUE_WITH(closure);
+}
+
+static upb_flow_t upb_endsubmsg_nop(void *closure, upb_value fval) {
+ (void)closure;
+ (void)fval;
+ return UPB_CONTINUE;
+}
+
+static upb_flow_t upb_unknownval_nop(void *closure, upb_field_number_t fieldnum,
+ upb_value val) {
+ (void)closure;
+ (void)fieldnum;
+ (void)val;
+ return UPB_CONTINUE;
+}
+
+static void upb_msgent_init(upb_handlers_msgent *e) {
+ upb_inttable_init(&e->fieldtab, 8, sizeof(upb_handlers_fieldent));
+ e->startmsg = &upb_startmsg_nop;
+ e->endmsg = &upb_endmsg_nop;
+ e->unknownval = &upb_unknownval_nop;
+}
+
+void upb_handlers_init(upb_handlers *h, upb_msgdef *md) {
+ h->msgs_len = 1;
+ h->msgs_size = 4;
+ h->msgs = malloc(h->msgs_size * sizeof(*h->msgs));
+ h->top = &h->stack[0];
+ h->limit = &h->stack[UPB_MAX_TYPE_DEPTH];
+ h->toplevel_msgdef = md;
+ if (md) upb_msgdef_ref(md);
+
+ h->top->msgent_index = 0;
+ h->top->msgdef = md;
+ h->msgent = &h->msgs[0];
+ upb_msgent_init(h->msgent);
+}
+
+void upb_handlers_uninit(upb_handlers *h) {
+ for (int i = 0; i < h->msgs_len; i++) upb_inttable_free(&h->msgs[i].fieldtab);
+ free(h->msgs);
+ upb_msgdef_unref(h->toplevel_msgdef);
+}
+
+static upb_handlers_fieldent *upb_handlers_getorcreate_without_fval(
+ upb_handlers *h, upb_field_number_t fieldnum, upb_fieldtype_t type) {
+ upb_handlers_fieldent *f =
+ upb_inttable_lookup(&h->msgent->fieldtab, fieldnum);
+ if (!f) {
+ upb_wire_type_t native_wire_type = upb_types[type].native_wire_type;
+ upb_handlers_fieldent new_f = {
+ false, type, native_wire_type, -1, UPB_NO_VALUE,
+ {&upb_value_nop}, &upb_endsubmsg_nop};
+ if (upb_issubmsgtype(type)) new_f.cb.startsubmsg = &upb_startsubmsg_nop;
+ upb_inttable_insert(&h->msgent->fieldtab, fieldnum, &new_f);
+
+ f = upb_inttable_lookup(&h->msgent->fieldtab, fieldnum);
+ assert(f);
+ }
+ assert(f->type == type);
+ return f;
+}
+
+static upb_handlers_fieldent *upb_handlers_getorcreate(
+ upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type, upb_value fval) {
+ upb_handlers_fieldent *f =
+ upb_handlers_getorcreate_without_fval(h, fieldnum, type);
+ f->fval = fval;
+ return f;
+}
+
+void upb_register_startend(upb_handlers *h, upb_startmsg_handler_t startmsg,
+ upb_endmsg_handler_t endmsg) {
+ h->msgent->startmsg = startmsg ? startmsg : &upb_startmsg_nop;
+ h->msgent->endmsg = endmsg ? endmsg : &upb_endmsg_nop;
+}
+
+// TODO:
+// void upb_register_unknownval(upb_handlers *h,
+// upb_unknownval_handler_t unknown);
+// bool upb_handlers_link(upb_handlers *h, upb_fielddef *f);
+// void upb_register_path_value(upb_handlers *h, const char *path,
+// upb_value_handler_t value, upb_value fval);
+
+void upb_register_all(upb_handlers *h, upb_startmsg_handler_t start,
+ upb_endmsg_handler_t end,
+ upb_value_handler_t value,
+ upb_startsubmsg_handler_t startsubmsg,
+ upb_endsubmsg_handler_t endsubmsg,
+ upb_unknownval_handler_t unknown) {
+ upb_register_startend(h, start, end);
+ //upb_register_unknownval(h, unknown);
+ upb_msgdef *m = h->top->msgdef;
+ upb_msg_iter i;
+ for(i = upb_msg_begin(m); !upb_msg_done(i); i = upb_msg_next(m, i)) {
+ upb_fielddef *f = upb_msg_iter_field(i);
+ upb_value fval;
+ upb_value_setfielddef(&fval, f);
+ if (upb_issubmsg(f)) {
+ upb_handlers_push(h, f, startsubmsg, endsubmsg, fval, false);
+ upb_register_all(h, start, end, value, startsubmsg, endsubmsg, unknown);
+ upb_handlers_pop(h, f);
+ } else {
+ upb_register_value(h, f, value, fval);
+ }
+ }
+}
+
+void upb_register_typed_value(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type, upb_value_handler_t value,
+ upb_value fval) {
+ upb_handlers_getorcreate(h, fieldnum, type, fval)->cb.value =
+ value ? value : &upb_value_nop;
+}
+
+void upb_register_value(upb_handlers *h, upb_fielddef *f,
+ upb_value_handler_t value, upb_value fval) {
+ assert(f->msgdef == h->top->msgdef);
+ upb_register_typed_value(h, f->number, f->type, value, fval);
+}
+
+void upb_register_typed_submsg(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type,
+ upb_startsubmsg_handler_t start,
+ upb_endsubmsg_handler_t end,
+ upb_value fval) {
+ upb_handlers_fieldent *f = upb_handlers_getorcreate(h, fieldnum, type, fval);
+ f->cb.startsubmsg = start ? start : &upb_startsubmsg_nop;
+ f->endsubmsg = end ? end : &upb_endsubmsg_nop;
+}
+
+void upb_handlers_typed_link(upb_handlers *h,
+ upb_field_number_t fieldnum,
+ upb_fieldtype_t type,
+ int frames) {
+ assert(frames <= (h->top - h->stack));
+ upb_handlers_fieldent *f =
+ upb_handlers_getorcreate_without_fval(h, fieldnum, type);
+ f->msgent_index = (h->top - frames)->msgent_index;
+}
+
+void upb_handlers_typed_push(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type) {
+ upb_handlers_fieldent *f =
+ upb_handlers_getorcreate_without_fval(h, fieldnum, type);
+ if (h->top == h->limit) abort(); // TODO: make growable.
+ ++h->top;
+ if (f->msgent_index == -1) {
+ // Need to push a new msgent.
+ if (h->msgs_size == h->msgs_len) {
+ h->msgs_size *= 2;
+ h->msgs = realloc(h->msgs, h->msgs_size * sizeof(*h->msgs));
+ }
+ f->msgent_index = h->msgs_len++;
+ h->msgent = &h->msgs[f->msgent_index];
+ upb_msgent_init(h->msgent);
+ } else {
+ h->msgent = &h->msgs[f->msgent_index];
+ }
+ h->top->msgent_index = f->msgent_index;
+ if (h->toplevel_msgdef) {
+ upb_fielddef *f = upb_msgdef_itof((h->top - 1)->msgdef, fieldnum);
+ assert(f);
+ h->top->msgdef = upb_downcast_msgdef(f->def);
+ }
+}
+
+void upb_handlers_push(upb_handlers *h, upb_fielddef *f,
+ upb_startsubmsg_handler_t start,
+ upb_endsubmsg_handler_t end, upb_value fval,
+ bool delegate) {
+ assert(f->msgdef == h->top->msgdef);
+ (void)delegate; // TODO
+ upb_register_typed_submsg(h, f->number, f->type, start, end, fval);
+ upb_handlers_typed_push(h, f->number, f->type);
+}
+
+void upb_handlers_typed_pop(upb_handlers *h) {
+ assert(h->top > h->stack);
+ --h->top;
+ h->msgent = &h->msgs[h->top->msgent_index];
+}
+
+void upb_handlers_pop(upb_handlers *h, upb_fielddef *f) {
+ (void)f; // TODO: Check that this matches the corresponding push.
+ upb_handlers_typed_pop(h);
+}
+
+/* upb_dispatcher *************************************************************/
+
+static upb_handlers_fieldent toplevel_f = {
+ false, 0, 0, 0, // The one value that is actually read
+#ifdef NDEBUG
+ {{0}},
+#else
+ {{0}, UPB_VALUETYPE_RAW},
+#endif
+ {NULL}, NULL};
+
+void upb_dispatcher_init(upb_dispatcher *d, upb_handlers *h,
+ size_t top_end_offset) {
+ d->handlers = h;
+ for (int i = 0; i < h->msgs_len; i++)
+ upb_inttable_compact(&h->msgs[i].fieldtab);
+ d->stack[0].end_offset = top_end_offset;
+ d->stack[0].f = &toplevel_f;
+ upb_status_init(&d->status);
+}
+
+void upb_dispatcher_reset(upb_dispatcher *d) {
+ d->msgent = &d->handlers->msgs[0];
+ d->dispatch_table = &d->msgent->fieldtab;
+ d->current_depth = 0;
+ d->skip_depth = INT_MAX;
+ d->noframe_depth = INT_MAX;
+ d->delegated_depth = 0;
+ d->top = d->stack;
+ d->limit = &d->stack[UPB_MAX_NESTING];
+}
+
+void upb_dispatcher_uninit(upb_dispatcher *d) {
+ upb_status_uninit(&d->status);
+}
+
+void upb_dispatcher_break(upb_dispatcher *d) {
+ assert(d->skip_depth == INT_MAX);
+ assert(d->noframe_depth == INT_MAX);
+ d->noframe_depth = d->current_depth;
+}
+
+upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d, void *closure) {
+ d->top->closure = closure;
+ upb_flow_t flow = d->msgent->startmsg(closure);
+ if (flow != UPB_CONTINUE) {
+ d->noframe_depth = d->current_depth + 1;
+ d->skip_depth = (flow == UPB_BREAK) ? d->delegated_depth : d->current_depth;
+ return UPB_SKIPSUBMSG;
+ }
+ return UPB_CONTINUE;
+}
+
+void upb_dispatch_endmsg(upb_dispatcher *d, upb_status *status) {
+ assert(d->top == d->stack);
+ d->msgent->endmsg(d->top->closure, &d->status);
+ // TODO: should we avoid this copy by passing client's status obj to cbs?
+ upb_copyerr(status, &d->status);
+}
+
+upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
+ upb_dispatcher_field *f,
+ size_t userval) {
+ ++d->current_depth;
+ if (upb_dispatcher_skipping(d)) return UPB_SKIPSUBMSG;
+ upb_sflow_t sflow = f->cb.startsubmsg(d->top->closure, f->fval);
+ if (sflow.flow != UPB_CONTINUE) {
+ d->noframe_depth = d->current_depth;
+ d->skip_depth = (sflow.flow == UPB_BREAK) ?
+ d->delegated_depth : d->current_depth;
+ return UPB_SKIPSUBMSG;
+ }
+
+ ++d->top;
+ if(d->top >= d->limit) {
+ upb_seterr(&d->status, UPB_ERROR, "Nesting too deep.");
+ d->noframe_depth = d->current_depth;
+ d->skip_depth = d->delegated_depth;
+ return UPB_SKIPSUBMSG;
+ }
+ d->top->f = f;
+ d->top->end_offset = userval;
+ d->top->closure = sflow.closure;
+ d->msgent = upb_handlers_getmsgent(d->handlers, f);
+ d->dispatch_table = &d->msgent->fieldtab;
+ return upb_dispatch_startmsg(d, d->top->closure);
+}
+
+upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d) {
+ upb_flow_t flow;
+ if (upb_dispatcher_noframe(d)) {
+ flow = UPB_SKIPSUBMSG;
+ } else {
+ assert(d->top > d->stack);
+ upb_dispatcher_field *old_f = d->top->f;
+ d->msgent->endmsg(d->top->closure, &d->status);
+ --d->top;
+ d->msgent = upb_handlers_getmsgent(d->handlers, d->top->f);
+ d->dispatch_table = &d->msgent->fieldtab;
+ d->noframe_depth = INT_MAX;
+ if (!upb_dispatcher_skipping(d)) d->skip_depth = INT_MAX;
+ // Deliver like a regular value.
+ flow = old_f->endsubmsg(d->top->closure, old_f->fval);
+ }
+ --d->current_depth;
+ return flow;
+}
diff --git a/src/upb_stream.h b/src/upb_stream.h
index 34e2710..9221a6b 100644
--- a/src/upb_stream.h
+++ b/src/upb_stream.h
@@ -1,26 +1,12 @@
/*
* upb - a minimalist implementation of protocol buffers.
*
- * This file defines four general-purpose streaming data interfaces.
+ * This file defines general-purpose streaming data interfaces:
*
* - upb_handlers: represents a set of callbacks, very much like in XML's SAX
* API, that a client can register to do a streaming tree traversal over a
* stream of structured protobuf data, without knowing where that data is
- * coming from. There is only one upb_handlers type (it is not a virtual
- * base class), but the object lets you register any set of handlers.
- *
- * The upb_handlers interface supports delegation: when entering a submessage,
- * you can delegate to another set of upb_handlers instead of handling the
- * submessage yourself. This allows upb_handlers objects to *compose* -- you
- * can implement a set of upb_handlers without knowing or caring whether this
- * is the top-level message or not.
- *
- * The other interfaces are the C equivalent of "virtual base classes" that
- * anyone can implement:
- *
- * - upb_src: an interface that represents a source of streaming protobuf data.
- * It lets you register a set of upb_handlers, and then call upb_src_run(),
- * which pulls the protobuf data from somewhere and then calls the handlers.
+ * coming from.
*
* - upb_bytesrc: a pull interface for streams of bytes, basically an
* abstraction of read()/fread(), but it avoids copies where possible.
@@ -42,92 +28,149 @@
#ifndef UPB_STREAM_H
#define UPB_STREAM_H
+#include <limits.h>
#include "upb.h"
+#include "upb_def.h"
#ifdef __cplusplus
extern "C" {
#endif
-// Forward-declare. We can't include upb_def.h; it would be circular.
-struct _upb_fielddef;
-
/* upb_handlers ***************************************************************/
-// upb_handlers define the interface by which a upb_src passes data to a
-// upb_sink.
+// A upb_handlers object is a table of callbacks that are bound to specific
+// messages and fields. A consumer of data registers callbacks and then
+// passes the upb_handlers object to the producer, which calls them at the
+// appropriate times.
-// Constants that a handler returns to indicate to its caller whether it should
-// continue or not.
+// All handlers except the endmsg handler return a value from this enum, to
+// control whether parsing will continue or not.
typedef enum {
- // Caller should continue sending values to the sink.
+ // Data source should continue calling callbacks.
UPB_CONTINUE = 0,
- // Stop processing for now; check status for details. If no status was set,
- // a generic error will be returned. If the error is resumable, it is not
- // (yet) defined where processing will resume -- waiting for real-world
- // examples of resumable decoders and resume-requiring clients. upb_src
- // implementations that are not capable of resuming will override the return
- // status to be non-resumable if a resumable status was set by the handlers.
+ // Halt processing permanently (in a non-resumable way). The endmsg handlers
+ // for any currently open messages will be called which can supply a more
+ // specific status message. If UPB_BREAK is returned from inside a delegated
+ // message, processing will continue normally in the containing message (though
+ // the containing message can inspect the returned status and choose to also
+ // return UPB_BREAK if it is not ok).
UPB_BREAK,
// Skips to the end of the current submessage (or if we are at the top
- // level, skips to the end of the entire message).
+ // level, skips to the end of the entire message). In other words, it is
+ // like a UPB_BREAK that applies only to the current level.
+ //
+ // If you UPB_SKIPSUBMSG from a startmsg handler, the endmsg handler will
+ // be called to perform cleanup and return a status. Returning
+ // UPB_SKIPSUBMSG from a startsubmsg handler will *not* call the startmsg,
+ // endmsg, or endsubmsg handlers.
UPB_SKIPSUBMSG,
- // When returned from a startsubmsg handler, indicates that the submessage
- // should be handled by a different set of handlers, which have been
- // registered on the provided upb_handlers object. This allows upb_handlers
- // objects to compose; a set of upb_handlers need not know whether it is the
- // top-level message or a sub-message. May not be returned from any other
- // callback.
- //
- // WARNING! The delegation API is slated for some significant changes.
- // See: http://code.google.com/p/upb/issues/detail?id=6
- UPB_DELEGATE,
+ // TODO: Add UPB_SUSPEND, for resumable producers/consumers.
} upb_flow_t;
-// upb_handlers
-struct _upb_handlers;
+typedef struct _upb_sflow upb_sflow_t;
+typedef upb_flow_t (*upb_startmsg_handler_t)(void *closure);
+typedef void (*upb_endmsg_handler_t)(void *closure, upb_status *status);
+typedef upb_flow_t (*upb_value_handler_t)(
+ void *closure, upb_value fval, upb_value val);
+typedef upb_sflow_t (*upb_startsubmsg_handler_t)(
+ void *closure, upb_value fval);
+typedef upb_flow_t (*upb_endsubmsg_handler_t)(void *closure, upb_value fval);
+typedef upb_flow_t (*upb_unknownval_handler_t)(
+ void *closure, upb_field_number_t fieldnum, upb_value val);
+
+typedef struct {
+ bool junk;
+ upb_fieldtype_t type;
+ upb_wire_type_t native_wire_type;
+ // For upb_issubmsg(f) only, the index into the msgdef array of the submsg.
+ // -1 if unset (indicates that submsg should be skipped).
+ int32_t msgent_index;
+ upb_value fval;
+ union {
+ upb_value_handler_t value;
+ upb_startsubmsg_handler_t startsubmsg;
+ } cb;
+ upb_endsubmsg_handler_t endsubmsg;
+} upb_handlers_fieldent;
+
+typedef struct {
+ upb_startmsg_handler_t startmsg;
+ upb_endmsg_handler_t endmsg;
+ upb_unknownval_handler_t unknownval;
+ // Maps field number -> upb_handlers_fieldent.
+ upb_inttable fieldtab;
+} upb_handlers_msgent;
+
+typedef struct {
+ upb_msgdef *msgdef;
+ int msgent_index;
+} upb_handlers_frame;
+
+struct _upb_handlers {
+ // Array of msgdefs, [0]=toplevel.
+ upb_handlers_msgent *msgs;
+ int msgs_len, msgs_size;
+ upb_msgdef *toplevel_msgdef; // We own a ref.
+ upb_handlers_msgent *msgent;
+ upb_handlers_frame stack[UPB_MAX_TYPE_DEPTH], *top, *limit;
+};
typedef struct _upb_handlers upb_handlers;
-typedef upb_flow_t (*upb_startmsg_handler_t)(void *closure);
-typedef upb_flow_t (*upb_endmsg_handler_t)(void *closure);
-typedef upb_flow_t (*upb_value_handler_t)(void *closure,
- struct _upb_fielddef *f,
- upb_value val);
-typedef upb_flow_t (*upb_startsubmsg_handler_t)(void *closure,
- struct _upb_fielddef *f,
- upb_handlers *delegate_to);
-typedef upb_flow_t (*upb_endsubmsg_handler_t)(void *closure,
- struct _upb_fielddef *f);
-typedef upb_flow_t (*upb_unknownval_handler_t)(void *closure,
- upb_field_number_t fieldnum,
- upb_value val);
-
-// An empty set of handlers, for convenient copy/paste:
+// The handlers object takes a ref on md. md can be NULL iff the client calls
+// only upb_*_typed_*() (only upb_symtab should do this).
+void upb_handlers_init(upb_handlers *h, upb_msgdef *md);
+void upb_handlers_uninit(upb_handlers *h);
+
+// The startsubmsg handler needs to also pass a closure to the submsg.
+struct _upb_sflow {
+ upb_flow_t flow;
+ void *closure;
+};
+INLINE upb_sflow_t UPB_SFLOW(upb_flow_t flow, void *closure) {
+ upb_sflow_t ret = {flow, closure};
+ return ret;
+}
+#define UPB_CONTINUE_WITH(c) UPB_SFLOW(UPB_CONTINUE, c)
+#define UPB_S_BREAK UPB_SFLOW(UPB_BREAK, NULL)
+
+// Each message can have its own set of handlers. Here are empty definitions
+// of the handlers for convenient copy/paste.
+// TODO: Should endsubmsg get a copy of the upb_status*, so it can decide what
+// to do in the case of a delegated failure?
//
// static upb_flow_t startmsg(void *closure) {
-// // Called when the top-level message begins.
+// // Called when the message begins. "closure" was supplied by our caller.
+// // "mval" is whatever was bound to this message at registration time (for
+// // upb_register_all() it will be its upb_msgdef*).
// return UPB_CONTINUE;
// }
//
-// static upb_flow_t endmsg(void *closure) {
-// // Called when the top-level message ends.
-// return UPB_CONTINUE;
+// static void endmsg(void *closure, upb_status *status) {
+// // Called when processing of this top-level message ends, whether in
+// // success or failure. "status" indicates the final status of processing,
+// // and can also be modified in-place to update the final status.
+// //
+// // Since this callback is guaranteed to always be called eventually, it
+// // can be used to free any resources that were allocated during processing.
// }
//
-// static upb_flow_t value(void *closure, upb_fielddef *f, upb_value val) {
-// // Called for every value in the stream.
+// static upb_flow_t value(void *closure, upb_value fval, upb_value val) {
+// // Called for every non-submessage value in the stream. "fval" contains
+// // whatever value was bound to this field at registration type
+// // (for upb_register_all(), this will be the field's upb_fielddef*).
// return UPB_CONTINUE;
// }
//
-// static upb_flow_t startsubmsg(void *closure, upb_fielddef *f,
-// upb_handlers *delegate_to) {
-// // Called when a submessage begins; can delegate by returning UPB_DELEGATE.
-// return UPB_CONTINUE;
+// static upb_sflow_t startsubmsg(void *closure, upb_value fval) {
+// // Called when a submessage begins. The second element of the return
+// // value is the closure for the submessage.
+// return UPB_CONTINUE_WITH(closure);
// }
//
-// static upb_flow_t endsubmsg(void *closure, upb_fielddef *f) {
+// static upb_flow_t endsubmsg(void *closure, upb_value fval) {
// // Called when a submessage ends.
// return UPB_CONTINUE;
// }
@@ -137,91 +180,222 @@ typedef upb_flow_t (*upb_unknownval_handler_t)(void *closure,
// // Called with an unknown value is encountered.
// return UPB_CONTINUE;
// }
-//
-// // Any handlers you don't need can be set to NULL.
-// static upb_handlerset handlers = {
-// startmsg,
-// endmsg,
-// value,
-// startsubmsg,
-// endsubmsg,
-// unknownval,
-// };
-typedef struct {
- upb_startmsg_handler_t startmsg;
- upb_endmsg_handler_t endmsg;
- upb_value_handler_t value;
- upb_startsubmsg_handler_t startsubmsg;
- upb_endsubmsg_handler_t endsubmsg;
- upb_unknownval_handler_t unknownval;
-} upb_handlerset;
-// Functions to register handlers on a upb_handlers object.
-INLINE void upb_handlers_init(upb_handlers *h);
-INLINE void upb_handlers_uninit(upb_handlers *h);
-INLINE void upb_handlers_reset(upb_handlers *h);
-INLINE bool upb_handlers_isempty(upb_handlers *h);
-INLINE void upb_register_handlerset(upb_handlers *h, upb_handlerset *set);
+// Functions to register the above handlers.
+// TODO: as an optimization, we could special-case handlers that don't
+// need fval, to avoid even generating the code that sets the argument.
+// If a value does not have a handler registered and there is no unknownval
+// handler, the value will be skipped.
+void upb_register_startend(upb_handlers *h, upb_startmsg_handler_t startmsg,
+ upb_endmsg_handler_t endmsg);
+void upb_register_value(upb_handlers *h, upb_fielddef *f,
+ upb_value_handler_t value, upb_value fval);
+void upb_register_unknownval(upb_handlers *h, upb_unknownval_handler_t unknown);
+
+// To register handlers for a submessage, push the fielddef and pop it
+// when you're done. This can be used to delegate a submessage to a
+// different processing component which does not need to be aware whether
+// it is at the top level or not.
+void upb_handlers_push(upb_handlers *h, upb_fielddef *f,
+ upb_startsubmsg_handler_t start,
+ upb_endsubmsg_handler_t end, upb_value fval,
+ bool delegate);
+void upb_handlers_pop(upb_handlers *h, upb_fielddef *f);
+
+// In the case where types are self-recursive or mutually recursive, you can
+// use this function which will link a set of handlers to a set that is
+// already on our stack. This allows us to handle a tree of arbitrary
+// depth without having to register an arbitrary number of levels of handlers.
+// Returns "true" if the given type is indeed on the stack already and was
+// linked.
+//
+// If more than one message of this type is on the stack, it chooses the
+// one that is deepest in the tree (if necessary, we could give the caller
+// more control over this).
+bool upb_handlers_link(upb_handlers *h, upb_fielddef *f);
+
+// Convenience function for registering the given handler for the given
+// field path. This will overwrite any startsubmsg handlers that were
+// previously registered along the path. These can be overwritten again
+// later if desired.
+// TODO: upb_register_path_submsg()?
+void upb_register_path_value(upb_handlers *h, const char *path,
+ upb_value_handler_t value, upb_value fval);
+
+// Convenience function for registering a single set of handlers on every
+// message in our hierarchy. mvals are bound to upb_msgdef* and fvals are
+// bound to upb_fielddef*. Any of the handlers can be NULL.
+void upb_register_all(upb_handlers *h, upb_startmsg_handler_t start,
+ upb_endmsg_handler_t end,
+ upb_value_handler_t value,
+ upb_startsubmsg_handler_t startsubmsg,
+ upb_endsubmsg_handler_t endsubmsg,
+ upb_unknownval_handler_t unknown);
// TODO: for clients that want to increase efficiency by preventing bytesrcs
// from automatically being converted to strings in the value callback.
-// INLINE void upb_handlers_use_bytesrcs(bool use_bytesrcs);
-
-// The closure will be passed to every handler. The status will be read by the
-// upb_src immediately after a handler has returned UPB_BREAK and used as the
-// overall upb_src status; it will not be referenced at any other time.
-INLINE void upb_set_handler_closure(upb_handlers *h, void *closure,
- upb_status *status);
-
-
-/* upb_src ********************************************************************/
-
-struct _upb_src;
-typedef struct _upb_src upb_src;
-
-// upb_src_sethandlers() must be called once and only once before upb_src_run()
-// is called. This sets up the callbacks that will handle the parse. A
-// upb_src that is fully initialized except for the call to
-// upb_src_sethandlers() is called "prepared" -- this is useful for library
-// functions that want to consume the output of a generic upb_src.
-// Calling sethandlers() multiple times is an error and will trigger an abort().
-INLINE void upb_src_sethandlers(upb_src *src, upb_handlers *handlers);
-
-// Runs the src, calling the callbacks that were registered with
-// upb_src_sethandlers(), and returning the status of the operation in
-// "status." The status might indicate UPB_TRYAGAIN (indicating EAGAIN on a
-// non-blocking socket) or a resumable error; in both cases upb_src_run can be
-// called again later. TRYAGAIN could come from either the src (input buffers
-// are empty) or the handlers (output buffers are full).
-INLINE void upb_src_run(upb_src *src, upb_status *status);
-
-
-// A convenience object that a upb_src can use to invoke handlers. It
-// transparently handles delegation so that the upb_src needs only follow the
-// protocol as if delegation did not exist.
-struct _upb_dispatcher;
-typedef struct _upb_dispatcher upb_dispatcher;
-INLINE void upb_dispatcher_init(upb_dispatcher *d);
-INLINE void upb_dispatcher_reset(upb_dispatcher *d, upb_handlers *h,
- bool supports_skip);
-INLINE upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d);
-INLINE upb_flow_t upb_dispatch_endmsg(upb_dispatcher *d);
-INLINE upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
- struct _upb_fielddef *f);
-INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d,
- struct _upb_fielddef *f);
-INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d, struct _upb_fielddef *f,
- upb_value val);
-INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d,
- upb_field_number_t fieldnum,
- upb_value val);
+// INLINE void upb_handlers_use_bytesrcs(upb_handlers *h, bool use_bytesrcs);
+
+// Low-level functions -- internal-only.
+void upb_register_typed_value(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type, upb_value_handler_t value,
+ upb_value fval);
+void upb_register_typed_submsg(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type,
+ upb_startsubmsg_handler_t start,
+ upb_endsubmsg_handler_t end,
+ upb_value fval);
+void upb_handlers_typed_link(upb_handlers *h,
+ upb_field_number_t fieldnum,
+ upb_fieldtype_t type,
+ int frames);
+void upb_handlers_typed_push(upb_handlers *h, upb_field_number_t fieldnum,
+ upb_fieldtype_t type);
+void upb_handlers_typed_pop(upb_handlers *h);
+
+INLINE upb_handlers_msgent *upb_handlers_getmsgent(upb_handlers *h,
+ upb_handlers_fieldent *f) {
+ assert(f->msgent_index != -1);
+ return &h->msgs[f->msgent_index];
+}
+upb_handlers_fieldent *upb_handlers_lookup(upb_inttable *dispatch_table, upb_field_number_t fieldnum);
+
+
+/* upb_dispatcher *************************************************************/
+
+// upb_dispatcher can be used by sources of data to invoke the appropriate
+// handlers. It takes care of details such as:
+// - ensuring all endmsg callbacks (cleanup handlers) are called.
+// - propagating status all the way back to the top-level message.
+// - handling UPB_BREAK properly (clients only need to handle UPB_SKIPSUBMSG).
+// - handling UPB_SKIPSUBMSG if the client doesn't (but this is less
+// efficient, because then you can't skip the actual work).
+// - tracking the stack of closures.
+//
+// TODO: it might be best to actually surface UPB_BREAK to clients in the case
+// that the can't efficiently skip the submsg; eg. with groups. Then the client
+// would know to just unwind the stack without bothering to consume the rest of
+// the input. On the other hand, it might be important for all the input to be
+// consumed, like if this is a submessage of a larger stream.
+
+typedef struct {
+ upb_handlers_fieldent *f;
+ void *closure;
+ size_t end_offset; // For groups, 0.
+} upb_dispatcher_frame;
+
+typedef struct {
+ upb_dispatcher_frame *top, *limit;
+
+ upb_handlers *handlers;
+
+ // Msg and dispatch table for the current level.
+ upb_handlers_msgent *msgent;
+ upb_inttable *dispatch_table;
+
+ // The number of startsubmsg calls without a corresponding endsubmsg call.
+ int current_depth;
+
+ // For all frames >= skip_depth, we are skipping all values in the submsg.
+ // For all frames >= noframe_depth, we did not even push a frame.
+ // These are INT_MAX when nothing is being skipped.
+ // Invariant: noframe_depth >= skip_depth
+ int skip_depth;
+ int noframe_depth;
+
+ // Depth of stack entries we'll skip if a callback returns UPB_BREAK.
+ int delegated_depth;
+
+ // Stack.
+ upb_dispatcher_frame stack[UPB_MAX_NESTING];
+ upb_status status;
+} upb_dispatcher;
+
+INLINE bool upb_dispatcher_skipping(upb_dispatcher *d) {
+ return d->current_depth >= d->skip_depth;
+}
+
+// If true, upb_dispatcher_skipping(d) must also be true.
+INLINE bool upb_dispatcher_noframe(upb_dispatcher *d) {
+ return d->current_depth >= d->noframe_depth;
+}
+
+
+typedef upb_handlers_fieldent upb_dispatcher_field;
+
+void upb_dispatcher_init(upb_dispatcher *d, upb_handlers *h, size_t top_end_offset);
+void upb_dispatcher_reset(upb_dispatcher *d);
+void upb_dispatcher_uninit(upb_dispatcher *d);
+
+upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d, void *closure);
+void upb_dispatch_endmsg(upb_dispatcher *d, upb_status *status);
+
+// Looks up a field by number for the current message.
+INLINE upb_dispatcher_field *upb_dispatcher_lookup(upb_dispatcher *d,
+ upb_field_number_t n) {
+ return (upb_dispatcher_field*)upb_inttable_fastlookup(
+ d->dispatch_table, n, sizeof(upb_dispatcher_field));
+}
+
+// Dispatches values or submessages -- the client is responsible for having
+// previously looked up the field.
+upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
+ upb_dispatcher_field *f,
+ size_t userval);
+upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d);
+
+INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d, upb_dispatcher_field *f,
+ upb_value val) {
+ if (upb_dispatcher_skipping(d)) return UPB_SKIPSUBMSG;
+ upb_flow_t flow = f->cb.value(d->top->closure, f->fval, val);
+ if (flow != UPB_CONTINUE) {
+ d->noframe_depth = d->current_depth + 1;
+ d->skip_depth = (flow == UPB_BREAK) ? d->delegated_depth : d->current_depth;
+ return UPB_SKIPSUBMSG;
+ }
+ return UPB_CONTINUE;
+}
+INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d, upb_field_number_t n,
+ upb_value val) {
+ // TODO.
+ (void)d;
+ (void)n;
+ (void)val;
+ return UPB_CONTINUE;
+}
+INLINE bool upb_dispatcher_stackempty(upb_dispatcher *d) {
+ return d->top == d->stack;
+}
/* upb_bytesrc ****************************************************************/
+// upb_bytesrc is a pull interface for streams of bytes, basically an
+// abstraction of read()/fread(), but it avoids copies where possible.
+
+typedef upb_strlen_t (*upb_bytesrc_read_fptr)(
+ upb_bytesrc *src, void *buf, upb_strlen_t count, upb_status *status);
+typedef bool (*upb_bytesrc_getstr_fptr)(
+ upb_bytesrc *src, upb_string *str, upb_status *status);
+
+typedef struct {
+ upb_bytesrc_read_fptr read;
+ upb_bytesrc_getstr_fptr getstr;
+} upb_bytesrc_vtbl;
+
+struct _upb_bytesrc {
+ upb_bytesrc_vtbl *vtbl;
+};
+
+INLINE void upb_bytesrc_init(upb_bytesrc *s, upb_bytesrc_vtbl *vtbl) {
+ s->vtbl = vtbl;
+}
+
// Reads up to "count" bytes into "buf", returning the total number of bytes
// read. If 0, indicates error and puts details in "status".
INLINE upb_strlen_t upb_bytesrc_read(upb_bytesrc *src, void *buf,
- upb_strlen_t count, upb_status *status);
+ upb_strlen_t count, upb_status *status) {
+ return src->vtbl->read(src, buf, count, status);
+}
// Like upb_bytesrc_read(), but modifies "str" in-place. Caller must ensure
// that "str" is created or just recycled. Returns "false" if no data was
@@ -234,22 +408,36 @@ INLINE upb_strlen_t upb_bytesrc_read(upb_bytesrc *src, void *buf,
// put it into a different kind of string object) then upb_bytesrc_get() could
// save you a copy.
INLINE bool upb_bytesrc_getstr(upb_bytesrc *src, upb_string *str,
- upb_status *status);
-
-// A convenience function for getting all the remaining data in a upb_bytesrc
-// as a upb_string. Returns false and sets "status" if the operation fails.
-INLINE bool upb_bytesrc_getfullstr(upb_bytesrc *src, upb_string *str,
- upb_status *status);
-INLINE bool upb_value_getfullstr(upb_value val, upb_string *str,
- upb_status *status) {
- return upb_bytesrc_getfullstr(upb_value_getbytesrc(val), str, status);
+ upb_status *status) {
+ return src->vtbl->getstr(src, str, status);
}
/* upb_bytesink ***************************************************************/
+// upb_bytesink: push interface for streams of bytes, basically an abstraction
+// of write()/fwrite(), but it avoids copies where possible.
+
struct _upb_bytesink;
typedef struct _upb_bytesink upb_bytesink;
+typedef upb_strlen_t (*upb_bytesink_putstr_fptr)(
+ upb_bytesink *bytesink, upb_string *str, upb_status *status);
+typedef upb_strlen_t (*upb_bytesink_vprintf_fptr)(
+ upb_bytesink *bytesink, upb_status *status, const char *fmt, va_list args);
+
+typedef struct {
+ upb_bytesink_putstr_fptr putstr;
+ upb_bytesink_vprintf_fptr vprintf;
+} upb_bytesink_vtbl;
+
+struct _upb_bytesink {
+ upb_bytesink_vtbl *vtbl;
+};
+
+INLINE void upb_bytesink_init(upb_bytesink *s, upb_bytesink_vtbl *vtbl) {
+ s->vtbl = vtbl;
+}
+
// TODO: Figure out how buffering should be handled. Should the caller buffer
// data and only call these functions when a buffer is full? Seems most
@@ -264,15 +452,21 @@ typedef struct _upb_bytesink upb_bytesink;
// Returns the number of bytes written.
INLINE upb_strlen_t upb_bytesink_printf(upb_bytesink *sink, upb_status *status,
- const char *fmt, ...);
+ const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ upb_strlen_t ret = sink->vtbl->vprintf(sink, status, fmt, args);
+ va_end(args);
+ return ret;
+}
// Puts the given string, returning true if the operation was successful, otherwise
// check "status" for details. Ownership of the string is *not* passed; if
// the callee wants a reference he must call upb_string_getref() on it.
INLINE upb_strlen_t upb_bytesink_putstr(upb_bytesink *sink, upb_string *str,
- upb_status *status);
-
-#include "upb_stream_vtbl.h"
+ upb_status *status) {
+ return sink->vtbl->putstr(sink, str, status);
+}
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/upb_stream_vtbl.h b/src/upb_stream_vtbl.h
deleted file mode 100644
index e9a4043..0000000
--- a/src/upb_stream_vtbl.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * upb - a minimalist implementation of protocol buffers.
- *
- * vtable declarations for types that are implementing any of the src or sink
- * interfaces. Only components that are implementing these interfaces need
- * to worry about this file.
- *
- * Copyright (c) 2010 Joshua Haberman. See LICENSE for details.
- */
-
-#ifndef UPB_SRCSINK_VTBL_H_
-#define UPB_SRCSINK_VTBL_H_
-
-#include <assert.h>
-#include "upb_stream.h"
-#include "upb_string.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Typedefs for function pointers to all of the virtual functions.
-
-// upb_src
-typedef void (*upb_src_sethandlers_fptr)(upb_src *src, upb_handlers *handlers);
-typedef void (*upb_src_run_fptr)(upb_src *src, upb_status *status);
-
-// upb_bytesrc.
-typedef upb_strlen_t (*upb_bytesrc_read_fptr)(
- upb_bytesrc *src, void *buf, upb_strlen_t count, upb_status *status);
-typedef bool (*upb_bytesrc_getstr_fptr)(
- upb_bytesrc *src, upb_string *str, upb_status *status);
-
-// upb_bytesink.
-typedef upb_strlen_t (*upb_bytesink_write_fptr)(
- upb_bytesink *bytesink, void *buf, upb_strlen_t count);
-typedef upb_strlen_t (*upb_bytesink_putstr_fptr)(
- upb_bytesink *bytesink, upb_string *str, upb_status *status);
-typedef upb_strlen_t (*upb_bytesink_vprintf_fptr)(
- upb_bytesink *bytesink, upb_status *status, const char *fmt, va_list args);
-
-// Vtables for the above interfaces.
-typedef struct {
- upb_bytesrc_read_fptr read;
- upb_bytesrc_getstr_fptr getstr;
-} upb_bytesrc_vtbl;
-
-typedef struct {
- upb_bytesink_write_fptr write;
- upb_bytesink_putstr_fptr putstr;
- upb_bytesink_vprintf_fptr vprintf;
-} upb_bytesink_vtbl;
-
-typedef struct {
- upb_src_sethandlers_fptr sethandlers;
- upb_src_run_fptr run;
-} upb_src_vtbl;
-
-
-// "Base Class" definitions; components that implement these interfaces should
-// contain one of these structures.
-
-struct _upb_bytesrc {
- upb_bytesrc_vtbl *vtbl;
-};
-
-struct _upb_bytesink {
- upb_bytesink_vtbl *vtbl;
-};
-
-struct _upb_src {
- upb_src_vtbl *vtbl;
-};
-
-INLINE void upb_bytesrc_init(upb_bytesrc *s, upb_bytesrc_vtbl *vtbl) {
- s->vtbl = vtbl;
-}
-
-INLINE void upb_bytesink_init(upb_bytesink *s, upb_bytesink_vtbl *vtbl) {
- s->vtbl = vtbl;
-}
-
-INLINE void upb_src_init(upb_src *s, upb_src_vtbl *vtbl) {
- s->vtbl = vtbl;
-}
-
-// Implementation of virtual function dispatch.
-
-// upb_src
-INLINE void upb_src_sethandlers(upb_src *src, upb_handlers *handlers) {
- src->vtbl->sethandlers(src, handlers);
-}
-
-INLINE void upb_src_run(upb_src *src, upb_status *status) {
- src->vtbl->run(src, status);
-}
-
-// upb_bytesrc
-INLINE upb_strlen_t upb_bytesrc_read(upb_bytesrc *src, void *buf,
- upb_strlen_t count, upb_status *status) {
- return src->vtbl->read(src, buf, count, status);
-}
-
-INLINE bool upb_bytesrc_getstr(upb_bytesrc *src, upb_string *str,
- upb_status *status) {
- return src->vtbl->getstr(src, str, status);
-}
-
-INLINE bool upb_bytesrc_getfullstr(upb_bytesrc *src, upb_string *str,
- upb_status *status) {
- // We start with a getstr, because that could possibly alias data instead of
- // copying.
- if (!upb_bytesrc_getstr(src, str, status)) return false;
- // Trade-off between number of read calls and amount of overallocation.
- const size_t bufsize = 4096;
- do {
- upb_strlen_t len = upb_string_len(str);
- char *buf = upb_string_getrwbuf(str, len + bufsize);
- upb_strlen_t read = upb_bytesrc_read(src, buf + len, bufsize, status);
- if (read < 0) return false;
- // Resize to proper size.
- upb_string_getrwbuf(str, len + read);
- } while (!status->code != UPB_EOF);
- return true;
-}
-
-
-// upb_bytesink
-INLINE upb_strlen_t upb_bytesink_write(upb_bytesink *sink, void *buf,
- upb_strlen_t count) {
- return sink->vtbl->write(sink, buf, count);
-}
-
-INLINE upb_strlen_t upb_bytesink_putstr(upb_bytesink *sink, upb_string *str, upb_status *status) {
- return sink->vtbl->putstr(sink, str, status);
-}
-
-INLINE upb_strlen_t upb_bytesink_printf(upb_bytesink *sink, upb_status *status, const char *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- upb_strlen_t ret = sink->vtbl->vprintf(sink, status, fmt, args);
- va_end(args);
- return ret;
-}
-
-// upb_handlers
-struct _upb_handlers {
- upb_handlerset *set;
- void *closure;
- upb_status *status; // We don't own this.
-};
-
-INLINE void upb_handlers_init(upb_handlers *h) {
- (void)h;
-}
-INLINE void upb_handlers_uninit(upb_handlers *h) {
- (void)h;
-}
-
-INLINE void upb_handlers_reset(upb_handlers *h) {
- h->set = NULL;
- h->closure = NULL;
-}
-
-INLINE bool upb_handlers_isempty(upb_handlers *h) {
- return !h->set && !h->closure;
-}
-
-INLINE upb_flow_t upb_nop(void *closure) {
- (void)closure;
- return UPB_CONTINUE;
-}
-
-INLINE upb_flow_t upb_value_nop(void *closure, struct _upb_fielddef *f, upb_value val) {
- (void)closure;
- (void)f;
- (void)val;
- return UPB_CONTINUE;
-}
-
-INLINE upb_flow_t upb_startsubmsg_nop(void *closure, struct _upb_fielddef *f,
- upb_handlers *delegate_to) {
- (void)closure;
- (void)f;
- (void)delegate_to;
- return UPB_CONTINUE;
-}
-
-INLINE upb_flow_t upb_endsubmsg_nop(void *closure, struct _upb_fielddef *f) {
- (void)closure;
- (void)f;
- return UPB_CONTINUE;
-}
-
-INLINE upb_flow_t upb_unknownval_nop(void *closure, upb_field_number_t fieldnum,
- upb_value val) {
- (void)closure;
- (void)fieldnum;
- (void)val;
- return UPB_CONTINUE;
-}
-
-INLINE void upb_register_handlerset(upb_handlers *h, upb_handlerset *set) {
- if (!set->startmsg) set->startmsg = &upb_nop;
- if (!set->endmsg) set->endmsg = &upb_nop;
- if (!set->value) set->value = &upb_value_nop;
- if (!set->startsubmsg) set->startsubmsg = &upb_startsubmsg_nop;
- if (!set->endsubmsg) set->endsubmsg = &upb_endsubmsg_nop;
- if (!set->unknownval) set->unknownval = &upb_unknownval_nop;
- h->set = set;
-}
-
-INLINE void upb_set_handler_closure(upb_handlers *h, void *closure,
- upb_status *status) {
- h->closure = closure;
- h->status = status;
-}
-
-// upb_dispatcher
-typedef struct {
- upb_handlers handlers;
- int depth;
-} upb_dispatcher_frame;
-
-struct _upb_dispatcher {
- upb_dispatcher_frame stack[UPB_MAX_NESTING], *top, *limit;
- bool supports_skip;
-};
-
-INLINE void upb_dispatcher_init(upb_dispatcher *d) {
- d->limit = d->stack + sizeof(d->stack);
-}
-
-INLINE void upb_dispatcher_reset(upb_dispatcher *d, upb_handlers *h,
- bool supports_skip) {
- d->top = d->stack;
- d->top->depth = 1; // Never want to trigger end-of-delegation.
- d->top->handlers = *h;
- d->supports_skip = supports_skip;
-}
-
-INLINE upb_flow_t upb_dispatch_startmsg(upb_dispatcher *d) {
- assert(d->stack == d->top);
- return d->top->handlers.set->startmsg(d->top->handlers.closure);
-}
-
-INLINE upb_flow_t upb_dispatch_endmsg(upb_dispatcher *d) {
- assert(d->stack == d->top);
- return d->top->handlers.set->endmsg(d->top->handlers.closure);
-}
-
-// TODO: several edge cases to fix:
-// - delegated start returns UPB_BREAK, should replay the start on resume.
-// - endsubmsg returns UPB_BREAK, should NOT replay the delegated endmsg.
-INLINE upb_flow_t upb_dispatch_startsubmsg(upb_dispatcher *d,
- struct _upb_fielddef *f) {
- upb_handlers handlers;
- upb_handlers_init(&handlers);
- upb_handlers_reset(&handlers);
- upb_flow_t ret = d->top->handlers.set->startsubmsg(d->top->handlers.closure, f, &handlers);
- assert((ret == UPB_DELEGATE) == !upb_handlers_isempty(&handlers));
- if (ret == UPB_DELEGATE) {
- ++d->top;
- d->top->handlers = handlers;
- d->top->depth = 0;
- ret = d->top->handlers.set->startmsg(d->top->handlers.closure);
- }
- if (ret == UPB_CONTINUE || !d->supports_skip) ++d->top->depth;
- upb_handlers_uninit(&handlers);
- return ret;
-}
-
-INLINE upb_flow_t upb_dispatch_endsubmsg(upb_dispatcher *d,
- struct _upb_fielddef *f) {
- upb_flow_t ret;
- if (--d->top->depth == 0) {
- ret = d->top->handlers.set->endmsg(d->top->handlers.closure);
- //assert(ret != UPB_BREAK);
- if (ret != UPB_CONTINUE) return ret;
- --d->top;
- assert(d->top >= d->stack);
- }
- return d->top->handlers.set->endsubmsg(d->top->handlers.closure, f);
-}
-
-INLINE upb_flow_t upb_dispatch_value(upb_dispatcher *d,
- struct _upb_fielddef *f,
- upb_value val) {
- return d->top->handlers.set->value(d->top->handlers.closure, f, val);
-}
-
-INLINE upb_flow_t upb_dispatch_unknownval(upb_dispatcher *d,
- upb_field_number_t fieldnum,
- upb_value val) {
- return d->top->handlers.set->unknownval(d->top->handlers.closure,
- fieldnum, val);
-}
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/src/upb_strstream.c b/src/upb_strstream.c
index c957648..8ef9884 100644
--- a/src/upb_strstream.c
+++ b/src/upb_strstream.c
@@ -7,7 +7,6 @@
#include "upb_strstream.h"
#include <stdlib.h>
-#include "upb_string.h"
/* upb_stringsrc **************************************************************/
@@ -108,7 +107,6 @@ static upb_strlen_t upb_stringsink_putstr(upb_bytesink *_sink, upb_string *str,
void upb_stringsink_init(upb_stringsink *s) {
static upb_bytesink_vtbl vtbl = {
- NULL,
upb_stringsink_putstr,
upb_stringsink_vprintf
};
diff --git a/src/upb_table.c b/src/upb_table.c
index d2cb5da..54af32d 100644
--- a/src/upb_table.c
+++ b/src/upb_table.c
@@ -7,7 +7,6 @@
*/
#include "upb_table.h"
-#include "upb_string.h"
#include <assert.h>
#include <stdlib.h>
diff --git a/src/upb_textprinter.c b/src/upb_textprinter.c
index 076e1df..6f123d6 100644
--- a/src/upb_textprinter.c
+++ b/src/upb_textprinter.c
@@ -9,8 +9,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <ctype.h>
-#include "upb_def.h"
-#include "upb_string.h"
struct _upb_textprinter {
upb_bytesink *bytesink;
@@ -91,9 +89,10 @@ err:
return -1;
}
-static upb_flow_t upb_textprinter_value(void *_p, upb_fielddef *f,
+static upb_flow_t upb_textprinter_value(void *_p, upb_value fval,
upb_value val) {
upb_textprinter *p = _p;
+ upb_fielddef *f = upb_value_getfielddef(fval);
upb_textprinter_indent(p);
CHECK(upb_bytesink_printf(p->bytesink, &p->status, UPB_STRFMT ": ", UPB_STRARG(f->name)));
#define CASE(fmtstr, member) \
@@ -144,21 +143,20 @@ err:
return UPB_BREAK;
}
-static upb_flow_t upb_textprinter_startsubmsg(void *_p, upb_fielddef *f,
- upb_handlers *delegate_to) {
- (void)delegate_to;
+static upb_sflow_t upb_textprinter_startsubmsg(void *_p, upb_value fval) {
upb_textprinter *p = _p;
+ upb_fielddef *f = upb_value_getfielddef(fval);
upb_textprinter_indent(p);
CHECK(upb_bytesink_printf(p->bytesink, &p->status, UPB_STRFMT " {", UPB_STRARG(f->name)));
if(!p->single_line) upb_bytesink_putstr(p->bytesink, UPB_STRLIT("\n"), &p->status);
p->indent_depth++;
- return UPB_CONTINUE;
+ return UPB_CONTINUE_WITH(_p);
err:
- return UPB_BREAK;
+ return UPB_S_BREAK;
}
-static upb_flow_t upb_textprinter_endsubmsg(void *_p, upb_fielddef *f) {
- (void)f;
+static upb_flow_t upb_textprinter_endsubmsg(void *_p, upb_value fval) {
+ (void)fval;
upb_textprinter *p = _p;
p->indent_depth--;
upb_textprinter_indent(p);
@@ -176,18 +174,20 @@ void upb_textprinter_free(upb_textprinter *p) {
free(p);
}
-void upb_textprinter_reset(upb_textprinter *p, upb_handlers *handlers,
- upb_bytesink *sink, bool single_line) {
- static upb_handlerset handlerset = {
+void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
+ bool single_line) {
+ p->bytesink = sink;
+ p->single_line = single_line;
+ p->indent_depth = 0;
+}
+
+void upb_textprinter_reghandlers(upb_handlers *h) {
+ upb_register_all(h,
NULL, // startmsg
NULL, // endmsg
upb_textprinter_value,
upb_textprinter_startsubmsg,
upb_textprinter_endsubmsg,
- };
- p->bytesink = sink;
- p->single_line = single_line;
- p->indent_depth = 0;
- upb_register_handlerset(handlers, &handlerset);
- upb_set_handler_closure(handlers, p, &p->status);
+ NULL // Unknown
+ );
}
diff --git a/src/upb_textprinter.h b/src/upb_textprinter.h
index a880626..40f392b 100644
--- a/src/upb_textprinter.h
+++ b/src/upb_textprinter.h
@@ -18,9 +18,9 @@ typedef struct _upb_textprinter upb_textprinter;
upb_textprinter *upb_textprinter_new();
void upb_textprinter_free(upb_textprinter *p);
-void upb_textprinter_reset(upb_textprinter *p, upb_handlers *handlers,
- upb_bytesink *sink, bool single_line);
-void upb_textprinter_sethandlers(upb_textprinter *p, upb_handlers *h);
+void upb_textprinter_reset(upb_textprinter *p, upb_bytesink *sink,
+ bool single_line);
+void upb_textprinter_reghandlers(upb_handlers *h);
#ifdef __cplusplus
} /* extern "C" */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback