Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 1 | // Protocol Buffers - Google's data interchange format |
| 2 | // Copyright 2014 Google Inc. All rights reserved. |
| 3 | // https://developers.google.com/protocol-buffers/ |
| 4 | // |
| 5 | // Redistribution and use in source and binary forms, with or without |
| 6 | // modification, are permitted provided that the following conditions are |
| 7 | // met: |
| 8 | // |
| 9 | // * Redistributions of source code must retain the above copyright |
| 10 | // notice, this list of conditions and the following disclaimer. |
| 11 | // * Redistributions in binary form must reproduce the above |
| 12 | // copyright notice, this list of conditions and the following disclaimer |
| 13 | // in the documentation and/or other materials provided with the |
| 14 | // distribution. |
| 15 | // * Neither the name of Google Inc. nor the names of its |
| 16 | // contributors may be used to endorse or promote products derived from |
| 17 | // this software without specific prior written permission. |
| 18 | // |
| 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | |
| 31 | #ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ |
| 32 | #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ |
| 33 | |
| 34 | #include <ruby/ruby.h> |
| 35 | #include <ruby/vm.h> |
| 36 | #include <ruby/encoding.h> |
| 37 | |
| 38 | #include "upb.h" |
| 39 | |
| 40 | // Forward decls. |
| 41 | struct DescriptorPool; |
| 42 | struct Descriptor; |
| 43 | struct FieldDescriptor; |
| 44 | struct EnumDescriptor; |
| 45 | struct MessageLayout; |
| 46 | struct MessageField; |
| 47 | struct MessageHeader; |
| 48 | struct MessageBuilderContext; |
| 49 | struct EnumBuilderContext; |
| 50 | struct Builder; |
| 51 | |
| 52 | typedef struct DescriptorPool DescriptorPool; |
| 53 | typedef struct Descriptor Descriptor; |
| 54 | typedef struct FieldDescriptor FieldDescriptor; |
| 55 | typedef struct OneofDescriptor OneofDescriptor; |
| 56 | typedef struct EnumDescriptor EnumDescriptor; |
| 57 | typedef struct MessageLayout MessageLayout; |
| 58 | typedef struct MessageField MessageField; |
| 59 | typedef struct MessageHeader MessageHeader; |
| 60 | typedef struct MessageBuilderContext MessageBuilderContext; |
| 61 | typedef struct OneofBuilderContext OneofBuilderContext; |
| 62 | typedef struct EnumBuilderContext EnumBuilderContext; |
| 63 | typedef struct Builder Builder; |
| 64 | |
| 65 | /* |
| 66 | It can be a bit confusing how the C structs defined below and the Ruby |
| 67 | objects interact and hold references to each other. First, a few principles: |
| 68 | |
| 69 | - Ruby's "TypedData" abstraction lets a Ruby VALUE hold a pointer to a C |
| 70 | struct (or arbitrary memory chunk), own it, and free it when collected. |
| 71 | Thus, each struct below will have a corresponding Ruby object |
| 72 | wrapping/owning it. |
| 73 | |
| 74 | - To get back from an underlying upb {msg,enum}def to the Ruby object, we |
| 75 | keep a global hashmap, accessed by get_def_obj/add_def_obj below. |
| 76 | |
| 77 | The in-memory structure is then something like: |
| 78 | |
| 79 | Ruby | upb |
| 80 | | |
| 81 | DescriptorPool ------------|-----------> upb_symtab____________________ |
| 82 | | | (message types) \ |
| 83 | | v \ |
| 84 | Descriptor ---------------|-----------> upb_msgdef (enum types)| |
| 85 | |--> msgclass | | ^ | |
| 86 | | (dynamically built) | | | (submsg fields) | |
| 87 | |--> MessageLayout | | | / |
| 88 | |--------------------------|> decoder method| | / |
| 89 | \--------------------------|> serialize | | / |
| 90 | | handlers v | / |
| 91 | FieldDescriptor -----------|-----------> upb_fielddef / |
| 92 | | | / |
| 93 | | v (enum fields) / |
| 94 | EnumDescriptor ------------|-----------> upb_enumdef <----------' |
| 95 | | |
| 96 | | |
| 97 | ^ | \___/ |
| 98 | `---------------|-----------------' (get_def_obj map) |
| 99 | */ |
| 100 | |
| 101 | // ----------------------------------------------------------------------------- |
| 102 | // Ruby class structure definitions. |
| 103 | // ----------------------------------------------------------------------------- |
| 104 | |
| 105 | struct DescriptorPool { |
| 106 | upb_symtab* symtab; |
| 107 | }; |
| 108 | |
| 109 | struct Descriptor { |
| 110 | const upb_msgdef* msgdef; |
| 111 | MessageLayout* layout; |
| 112 | VALUE klass; // begins as nil |
| 113 | const upb_handlers* fill_handlers; |
| 114 | const upb_pbdecodermethod* fill_method; |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 115 | const upb_json_parsermethod* json_fill_method; |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 116 | const upb_handlers* pb_serialize_handlers; |
| 117 | const upb_handlers* json_serialize_handlers; |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 118 | const upb_handlers* json_serialize_handlers_preserve; |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 119 | }; |
| 120 | |
| 121 | struct FieldDescriptor { |
| 122 | const upb_fielddef* fielddef; |
| 123 | }; |
| 124 | |
| 125 | struct OneofDescriptor { |
| 126 | const upb_oneofdef* oneofdef; |
| 127 | }; |
| 128 | |
| 129 | struct EnumDescriptor { |
| 130 | const upb_enumdef* enumdef; |
| 131 | VALUE module; // begins as nil |
| 132 | }; |
| 133 | |
| 134 | struct MessageBuilderContext { |
| 135 | VALUE descriptor; |
| 136 | VALUE builder; |
| 137 | }; |
| 138 | |
| 139 | struct OneofBuilderContext { |
| 140 | VALUE descriptor; |
| 141 | VALUE builder; |
| 142 | }; |
| 143 | |
| 144 | struct EnumBuilderContext { |
| 145 | VALUE enumdesc; |
| 146 | }; |
| 147 | |
| 148 | struct Builder { |
| 149 | VALUE pending_list; |
| 150 | upb_def** defs; // used only while finalizing |
| 151 | }; |
| 152 | |
| 153 | extern VALUE cDescriptorPool; |
| 154 | extern VALUE cDescriptor; |
| 155 | extern VALUE cFieldDescriptor; |
| 156 | extern VALUE cEnumDescriptor; |
| 157 | extern VALUE cMessageBuilderContext; |
| 158 | extern VALUE cOneofBuilderContext; |
| 159 | extern VALUE cEnumBuilderContext; |
| 160 | extern VALUE cBuilder; |
| 161 | |
| 162 | extern VALUE cError; |
| 163 | extern VALUE cParseError; |
| 164 | |
| 165 | // We forward-declare all of the Ruby method implementations here because we |
| 166 | // sometimes call the methods directly across .c files, rather than going |
| 167 | // through Ruby's method dispatching (e.g. during message parse). It's cleaner |
| 168 | // to keep the list of object methods together than to split them between |
| 169 | // static-in-file definitions and header declarations. |
| 170 | |
| 171 | void DescriptorPool_mark(void* _self); |
| 172 | void DescriptorPool_free(void* _self); |
| 173 | VALUE DescriptorPool_alloc(VALUE klass); |
| 174 | void DescriptorPool_register(VALUE module); |
| 175 | DescriptorPool* ruby_to_DescriptorPool(VALUE value); |
| 176 | VALUE DescriptorPool_add(VALUE _self, VALUE def); |
| 177 | VALUE DescriptorPool_build(VALUE _self); |
| 178 | VALUE DescriptorPool_lookup(VALUE _self, VALUE name); |
| 179 | VALUE DescriptorPool_generated_pool(VALUE _self); |
| 180 | |
| 181 | void Descriptor_mark(void* _self); |
| 182 | void Descriptor_free(void* _self); |
| 183 | VALUE Descriptor_alloc(VALUE klass); |
| 184 | void Descriptor_register(VALUE module); |
| 185 | Descriptor* ruby_to_Descriptor(VALUE value); |
| 186 | VALUE Descriptor_name(VALUE _self); |
| 187 | VALUE Descriptor_name_set(VALUE _self, VALUE str); |
| 188 | VALUE Descriptor_each(VALUE _self); |
| 189 | VALUE Descriptor_lookup(VALUE _self, VALUE name); |
| 190 | VALUE Descriptor_add_field(VALUE _self, VALUE obj); |
| 191 | VALUE Descriptor_add_oneof(VALUE _self, VALUE obj); |
| 192 | VALUE Descriptor_each_oneof(VALUE _self); |
| 193 | VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name); |
| 194 | VALUE Descriptor_msgclass(VALUE _self); |
| 195 | extern const rb_data_type_t _Descriptor_type; |
| 196 | |
| 197 | void FieldDescriptor_mark(void* _self); |
| 198 | void FieldDescriptor_free(void* _self); |
| 199 | VALUE FieldDescriptor_alloc(VALUE klass); |
| 200 | void FieldDescriptor_register(VALUE module); |
| 201 | FieldDescriptor* ruby_to_FieldDescriptor(VALUE value); |
| 202 | VALUE FieldDescriptor_name(VALUE _self); |
| 203 | VALUE FieldDescriptor_name_set(VALUE _self, VALUE str); |
| 204 | VALUE FieldDescriptor_type(VALUE _self); |
| 205 | VALUE FieldDescriptor_type_set(VALUE _self, VALUE type); |
| 206 | VALUE FieldDescriptor_label(VALUE _self); |
| 207 | VALUE FieldDescriptor_label_set(VALUE _self, VALUE label); |
| 208 | VALUE FieldDescriptor_number(VALUE _self); |
| 209 | VALUE FieldDescriptor_number_set(VALUE _self, VALUE number); |
| 210 | VALUE FieldDescriptor_submsg_name(VALUE _self); |
| 211 | VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value); |
| 212 | VALUE FieldDescriptor_subtype(VALUE _self); |
| 213 | VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb); |
| 214 | VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value); |
| 215 | upb_fieldtype_t ruby_to_fieldtype(VALUE type); |
| 216 | VALUE fieldtype_to_ruby(upb_fieldtype_t type); |
| 217 | |
| 218 | void OneofDescriptor_mark(void* _self); |
| 219 | void OneofDescriptor_free(void* _self); |
| 220 | VALUE OneofDescriptor_alloc(VALUE klass); |
| 221 | void OneofDescriptor_register(VALUE module); |
| 222 | OneofDescriptor* ruby_to_OneofDescriptor(VALUE value); |
| 223 | VALUE OneofDescriptor_name(VALUE _self); |
| 224 | VALUE OneofDescriptor_name_set(VALUE _self, VALUE value); |
| 225 | VALUE OneofDescriptor_add_field(VALUE _self, VALUE field); |
| 226 | VALUE OneofDescriptor_each(VALUE _self, VALUE field); |
| 227 | |
| 228 | void EnumDescriptor_mark(void* _self); |
| 229 | void EnumDescriptor_free(void* _self); |
| 230 | VALUE EnumDescriptor_alloc(VALUE klass); |
| 231 | void EnumDescriptor_register(VALUE module); |
| 232 | EnumDescriptor* ruby_to_EnumDescriptor(VALUE value); |
| 233 | VALUE EnumDescriptor_name(VALUE _self); |
| 234 | VALUE EnumDescriptor_name_set(VALUE _self, VALUE str); |
| 235 | VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number); |
| 236 | VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name); |
| 237 | VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number); |
| 238 | VALUE EnumDescriptor_each(VALUE _self); |
| 239 | VALUE EnumDescriptor_enummodule(VALUE _self); |
| 240 | extern const rb_data_type_t _EnumDescriptor_type; |
| 241 | |
| 242 | void MessageBuilderContext_mark(void* _self); |
| 243 | void MessageBuilderContext_free(void* _self); |
| 244 | VALUE MessageBuilderContext_alloc(VALUE klass); |
| 245 | void MessageBuilderContext_register(VALUE module); |
| 246 | MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE value); |
| 247 | VALUE MessageBuilderContext_initialize(VALUE _self, |
| 248 | VALUE descriptor, |
| 249 | VALUE builder); |
| 250 | VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self); |
| 251 | VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self); |
| 252 | VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self); |
| 253 | VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self); |
| 254 | VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name); |
| 255 | |
| 256 | void OneofBuilderContext_mark(void* _self); |
| 257 | void OneofBuilderContext_free(void* _self); |
| 258 | VALUE OneofBuilderContext_alloc(VALUE klass); |
| 259 | void OneofBuilderContext_register(VALUE module); |
| 260 | OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE value); |
| 261 | VALUE OneofBuilderContext_initialize(VALUE _self, |
| 262 | VALUE descriptor, |
| 263 | VALUE builder); |
| 264 | VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self); |
| 265 | |
| 266 | void EnumBuilderContext_mark(void* _self); |
| 267 | void EnumBuilderContext_free(void* _self); |
| 268 | VALUE EnumBuilderContext_alloc(VALUE klass); |
| 269 | void EnumBuilderContext_register(VALUE module); |
| 270 | EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE value); |
| 271 | VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdesc); |
| 272 | VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number); |
| 273 | |
| 274 | void Builder_mark(void* _self); |
| 275 | void Builder_free(void* _self); |
| 276 | VALUE Builder_alloc(VALUE klass); |
| 277 | void Builder_register(VALUE module); |
| 278 | Builder* ruby_to_Builder(VALUE value); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 279 | VALUE Builder_initialize(VALUE _self); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 280 | VALUE Builder_add_message(VALUE _self, VALUE name); |
| 281 | VALUE Builder_add_enum(VALUE _self, VALUE name); |
| 282 | VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb); |
| 283 | |
| 284 | // ----------------------------------------------------------------------------- |
| 285 | // Native slot storage abstraction. |
| 286 | // ----------------------------------------------------------------------------- |
| 287 | |
| 288 | #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t) |
| 289 | |
| 290 | size_t native_slot_size(upb_fieldtype_t type); |
| 291 | void native_slot_set(upb_fieldtype_t type, |
| 292 | VALUE type_class, |
| 293 | void* memory, |
| 294 | VALUE value); |
| 295 | // Atomically (with respect to Ruby VM calls) either update the value and set a |
| 296 | // oneof case, or do neither. If |case_memory| is null, then no case value is |
| 297 | // set. |
| 298 | void native_slot_set_value_and_case(upb_fieldtype_t type, |
| 299 | VALUE type_class, |
| 300 | void* memory, |
| 301 | VALUE value, |
| 302 | uint32_t* case_memory, |
| 303 | uint32_t case_number); |
| 304 | VALUE native_slot_get(upb_fieldtype_t type, |
| 305 | VALUE type_class, |
| 306 | const void* memory); |
| 307 | void native_slot_init(upb_fieldtype_t type, void* memory); |
| 308 | void native_slot_mark(upb_fieldtype_t type, void* memory); |
| 309 | void native_slot_dup(upb_fieldtype_t type, void* to, void* from); |
| 310 | void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from); |
| 311 | bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2); |
| 312 | |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 313 | VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 314 | void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value); |
| 315 | |
| 316 | extern rb_encoding* kRubyStringUtf8Encoding; |
| 317 | extern rb_encoding* kRubyStringASCIIEncoding; |
| 318 | extern rb_encoding* kRubyString8bitEncoding; |
| 319 | |
| 320 | VALUE field_type_class(const upb_fielddef* field); |
| 321 | |
| 322 | #define MAP_KEY_FIELD 1 |
| 323 | #define MAP_VALUE_FIELD 2 |
| 324 | |
| 325 | // Oneof case slot value to indicate that no oneof case is set. The value `0` is |
| 326 | // safe because field numbers are used as case identifiers, and no field can |
| 327 | // have a number of 0. |
| 328 | #define ONEOF_CASE_NONE 0 |
| 329 | |
| 330 | // These operate on a map field (i.e., a repeated field of submessages whose |
| 331 | // submessage type is a map-entry msgdef). |
| 332 | bool is_map_field(const upb_fielddef* field); |
| 333 | const upb_fielddef* map_field_key(const upb_fielddef* field); |
| 334 | const upb_fielddef* map_field_value(const upb_fielddef* field); |
| 335 | |
| 336 | // These operate on a map-entry msgdef. |
| 337 | const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); |
| 338 | const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); |
| 339 | |
| 340 | // ----------------------------------------------------------------------------- |
| 341 | // Repeated field container type. |
| 342 | // ----------------------------------------------------------------------------- |
| 343 | |
| 344 | typedef struct { |
| 345 | upb_fieldtype_t field_type; |
| 346 | VALUE field_type_class; |
| 347 | void* elements; |
| 348 | int size; |
| 349 | int capacity; |
| 350 | } RepeatedField; |
| 351 | |
| 352 | void RepeatedField_mark(void* self); |
| 353 | void RepeatedField_free(void* self); |
| 354 | VALUE RepeatedField_alloc(VALUE klass); |
| 355 | VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self); |
| 356 | void RepeatedField_register(VALUE module); |
| 357 | |
| 358 | extern const rb_data_type_t RepeatedField_type; |
| 359 | extern VALUE cRepeatedField; |
| 360 | |
| 361 | RepeatedField* ruby_to_RepeatedField(VALUE value); |
| 362 | |
| 363 | VALUE RepeatedField_each(VALUE _self); |
| 364 | VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self); |
| 365 | void* RepeatedField_index_native(VALUE _self, int index); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 366 | int RepeatedField_size(VALUE _self); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 367 | VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val); |
| 368 | void RepeatedField_reserve(RepeatedField* self, int new_size); |
| 369 | VALUE RepeatedField_push(VALUE _self, VALUE val); |
| 370 | void RepeatedField_push_native(VALUE _self, void* data); |
| 371 | VALUE RepeatedField_pop_one(VALUE _self); |
| 372 | VALUE RepeatedField_insert(int argc, VALUE* argv, VALUE _self); |
| 373 | VALUE RepeatedField_replace(VALUE _self, VALUE list); |
| 374 | VALUE RepeatedField_clear(VALUE _self); |
| 375 | VALUE RepeatedField_length(VALUE _self); |
| 376 | VALUE RepeatedField_dup(VALUE _self); |
| 377 | VALUE RepeatedField_deep_copy(VALUE _self); |
| 378 | VALUE RepeatedField_to_ary(VALUE _self); |
| 379 | VALUE RepeatedField_eq(VALUE _self, VALUE _other); |
| 380 | VALUE RepeatedField_hash(VALUE _self); |
| 381 | VALUE RepeatedField_inspect(VALUE _self); |
| 382 | VALUE RepeatedField_plus(VALUE _self, VALUE list); |
| 383 | |
| 384 | // Defined in repeated_field.c; also used by Map. |
| 385 | void validate_type_class(upb_fieldtype_t type, VALUE klass); |
| 386 | |
| 387 | // ----------------------------------------------------------------------------- |
| 388 | // Map container type. |
| 389 | // ----------------------------------------------------------------------------- |
| 390 | |
| 391 | typedef struct { |
| 392 | upb_fieldtype_t key_type; |
| 393 | upb_fieldtype_t value_type; |
| 394 | VALUE value_type_class; |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 395 | VALUE parse_frame; |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 396 | upb_strtable table; |
| 397 | } Map; |
| 398 | |
| 399 | void Map_mark(void* self); |
| 400 | void Map_free(void* self); |
| 401 | VALUE Map_alloc(VALUE klass); |
| 402 | VALUE Map_init(int argc, VALUE* argv, VALUE self); |
| 403 | void Map_register(VALUE module); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 404 | VALUE Map_set_frame(VALUE self, VALUE val); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 405 | |
| 406 | extern const rb_data_type_t Map_type; |
| 407 | extern VALUE cMap; |
| 408 | |
| 409 | Map* ruby_to_Map(VALUE value); |
| 410 | |
| 411 | VALUE Map_each(VALUE _self); |
| 412 | VALUE Map_keys(VALUE _self); |
| 413 | VALUE Map_values(VALUE _self); |
| 414 | VALUE Map_index(VALUE _self, VALUE key); |
| 415 | VALUE Map_index_set(VALUE _self, VALUE key, VALUE value); |
| 416 | VALUE Map_has_key(VALUE _self, VALUE key); |
| 417 | VALUE Map_delete(VALUE _self, VALUE key); |
| 418 | VALUE Map_clear(VALUE _self); |
| 419 | VALUE Map_length(VALUE _self); |
| 420 | VALUE Map_dup(VALUE _self); |
| 421 | VALUE Map_deep_copy(VALUE _self); |
| 422 | VALUE Map_eq(VALUE _self, VALUE _other); |
| 423 | VALUE Map_hash(VALUE _self); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 424 | VALUE Map_to_h(VALUE _self); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 425 | VALUE Map_inspect(VALUE _self); |
| 426 | VALUE Map_merge(VALUE _self, VALUE hashmap); |
| 427 | VALUE Map_merge_into_self(VALUE _self, VALUE hashmap); |
| 428 | |
| 429 | typedef struct { |
| 430 | Map* self; |
| 431 | upb_strtable_iter it; |
| 432 | } Map_iter; |
| 433 | |
| 434 | void Map_begin(VALUE _self, Map_iter* iter); |
| 435 | void Map_next(Map_iter* iter); |
| 436 | bool Map_done(Map_iter* iter); |
| 437 | VALUE Map_iter_key(Map_iter* iter); |
| 438 | VALUE Map_iter_value(Map_iter* iter); |
| 439 | |
| 440 | // ----------------------------------------------------------------------------- |
| 441 | // Message layout / storage. |
| 442 | // ----------------------------------------------------------------------------- |
| 443 | |
| 444 | #define MESSAGE_FIELD_NO_CASE ((size_t)-1) |
| 445 | |
| 446 | struct MessageField { |
| 447 | size_t offset; |
| 448 | size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. |
| 449 | }; |
| 450 | |
| 451 | struct MessageLayout { |
| 452 | const upb_msgdef* msgdef; |
| 453 | MessageField* fields; |
| 454 | size_t size; |
| 455 | }; |
| 456 | |
| 457 | MessageLayout* create_layout(const upb_msgdef* msgdef); |
| 458 | void free_layout(MessageLayout* layout); |
| 459 | VALUE layout_get(MessageLayout* layout, |
| 460 | const void* storage, |
| 461 | const upb_fielddef* field); |
| 462 | void layout_set(MessageLayout* layout, |
| 463 | void* storage, |
| 464 | const upb_fielddef* field, |
| 465 | VALUE val); |
| 466 | void layout_init(MessageLayout* layout, void* storage); |
| 467 | void layout_mark(MessageLayout* layout, void* storage); |
| 468 | void layout_dup(MessageLayout* layout, void* to, void* from); |
| 469 | void layout_deep_copy(MessageLayout* layout, void* to, void* from); |
| 470 | VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2); |
| 471 | VALUE layout_hash(MessageLayout* layout, void* storage); |
| 472 | VALUE layout_inspect(MessageLayout* layout, void* storage); |
| 473 | |
| 474 | // ----------------------------------------------------------------------------- |
| 475 | // Message class creation. |
| 476 | // ----------------------------------------------------------------------------- |
| 477 | |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 478 | // This should probably be factored into a common upb component. |
| 479 | |
| 480 | typedef struct { |
| 481 | upb_byteshandler handler; |
| 482 | upb_bytessink sink; |
| 483 | char *ptr; |
| 484 | size_t len, size; |
| 485 | } stringsink; |
| 486 | |
| 487 | void stringsink_uninit(stringsink *sink); |
| 488 | |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 489 | struct MessageHeader { |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 490 | Descriptor* descriptor; // kept alive by self.class.descriptor reference. |
| 491 | stringsink* unknown_fields; // store unknown fields in decoding. |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 492 | // Data comes after this. |
| 493 | }; |
| 494 | |
| 495 | extern rb_data_type_t Message_type; |
| 496 | |
| 497 | VALUE build_class_from_descriptor(Descriptor* descriptor); |
| 498 | void* Message_data(void* msg); |
| 499 | void Message_mark(void* self); |
| 500 | void Message_free(void* self); |
| 501 | VALUE Message_alloc(VALUE klass); |
| 502 | VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self); |
| 503 | VALUE Message_initialize(int argc, VALUE* argv, VALUE _self); |
| 504 | VALUE Message_dup(VALUE _self); |
| 505 | VALUE Message_deep_copy(VALUE _self); |
| 506 | VALUE Message_eq(VALUE _self, VALUE _other); |
| 507 | VALUE Message_hash(VALUE _self); |
| 508 | VALUE Message_inspect(VALUE _self); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 509 | VALUE Message_to_h(VALUE _self); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 510 | VALUE Message_index(VALUE _self, VALUE field_name); |
| 511 | VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value); |
| 512 | VALUE Message_descriptor(VALUE klass); |
| 513 | VALUE Message_decode(VALUE klass, VALUE data); |
| 514 | VALUE Message_encode(VALUE klass, VALUE msg_rb); |
| 515 | VALUE Message_decode_json(VALUE klass, VALUE data); |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 516 | VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 517 | |
Austin Schuh | 40c1652 | 2018-10-28 20:27:54 -0700 | [diff] [blame^] | 518 | VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb); |
Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame] | 519 | VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj); |
| 520 | |
| 521 | VALUE build_module_from_enumdesc(EnumDescriptor* enumdef); |
| 522 | VALUE enum_lookup(VALUE self, VALUE number); |
| 523 | VALUE enum_resolve(VALUE self, VALUE sym); |
| 524 | |
| 525 | const upb_pbdecodermethod *new_fillmsg_decodermethod( |
| 526 | Descriptor* descriptor, const void *owner); |
| 527 | |
| 528 | // Maximum depth allowed during encoding, to avoid stack overflows due to |
| 529 | // cycles. |
| 530 | #define ENCODE_MAX_NESTING 63 |
| 531 | |
| 532 | // ----------------------------------------------------------------------------- |
| 533 | // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor |
| 534 | // instances. |
| 535 | // ----------------------------------------------------------------------------- |
| 536 | void add_def_obj(const void* def, VALUE value); |
| 537 | VALUE get_def_obj(const void* def); |
| 538 | |
| 539 | // ----------------------------------------------------------------------------- |
| 540 | // Utilities. |
| 541 | // ----------------------------------------------------------------------------- |
| 542 | |
| 543 | void check_upb_status(const upb_status* status, const char* msg); |
| 544 | |
| 545 | #define CHECK_UPB(code, msg) do { \ |
| 546 | upb_status status = UPB_STATUS_INIT; \ |
| 547 | code; \ |
| 548 | check_upb_status(&status, msg); \ |
| 549 | } while (0) |
| 550 | |
| 551 | extern ID descriptor_instancevar_interned; |
| 552 | |
| 553 | #endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ |