|  | // Protocol Buffers - Google's data interchange format | 
|  | // Copyright 2014 Google Inc.  All rights reserved. | 
|  | // https://developers.google.com/protocol-buffers/ | 
|  | // | 
|  | // Redistribution and use in source and binary forms, with or without | 
|  | // modification, are permitted provided that the following conditions are | 
|  | // met: | 
|  | // | 
|  | //     * Redistributions of source code must retain the above copyright | 
|  | // notice, this list of conditions and the following disclaimer. | 
|  | //     * Redistributions in binary form must reproduce the above | 
|  | // copyright notice, this list of conditions and the following disclaimer | 
|  | // in the documentation and/or other materials provided with the | 
|  | // distribution. | 
|  | //     * Neither the name of Google Inc. nor the names of its | 
|  | // contributors may be used to endorse or promote products derived from | 
|  | // this software without specific prior written permission. | 
|  | // | 
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  |  | 
|  | #ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ | 
|  | #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ | 
|  |  | 
|  | #include <ruby/ruby.h> | 
|  | #include <ruby/vm.h> | 
|  | #include <ruby/encoding.h> | 
|  |  | 
|  | #include "upb.h" | 
|  |  | 
|  | // Forward decls. | 
|  | struct DescriptorPool; | 
|  | struct Descriptor; | 
|  | struct FileDescriptor; | 
|  | struct FieldDescriptor; | 
|  | struct EnumDescriptor; | 
|  | struct MessageLayout; | 
|  | struct MessageField; | 
|  | struct MessageHeader; | 
|  | struct MessageBuilderContext; | 
|  | struct EnumBuilderContext; | 
|  | struct FileBuilderContext; | 
|  | struct Builder; | 
|  |  | 
|  | typedef struct DescriptorPool DescriptorPool; | 
|  | typedef struct Descriptor Descriptor; | 
|  | typedef struct FileDescriptor FileDescriptor; | 
|  | typedef struct FieldDescriptor FieldDescriptor; | 
|  | typedef struct OneofDescriptor OneofDescriptor; | 
|  | typedef struct EnumDescriptor EnumDescriptor; | 
|  | typedef struct MessageLayout MessageLayout; | 
|  | typedef struct MessageField MessageField; | 
|  | typedef struct MessageHeader MessageHeader; | 
|  | typedef struct MessageBuilderContext MessageBuilderContext; | 
|  | typedef struct OneofBuilderContext OneofBuilderContext; | 
|  | typedef struct EnumBuilderContext EnumBuilderContext; | 
|  | typedef struct FileBuilderContext FileBuilderContext; | 
|  | typedef struct Builder Builder; | 
|  |  | 
|  | /* | 
|  | It can be a bit confusing how the C structs defined below and the Ruby | 
|  | objects interact and hold references to each other. First, a few principles: | 
|  |  | 
|  | - Ruby's "TypedData" abstraction lets a Ruby VALUE hold a pointer to a C | 
|  | struct (or arbitrary memory chunk), own it, and free it when collected. | 
|  | Thus, each struct below will have a corresponding Ruby object | 
|  | wrapping/owning it. | 
|  |  | 
|  | - To get back from an underlying upb {msg,enum}def to the Ruby object, we | 
|  | keep a global hashmap, accessed by get_def_obj/add_def_obj below. | 
|  |  | 
|  | The in-memory structure is then something like: | 
|  |  | 
|  | Ruby                        |      upb | 
|  | | | 
|  | DescriptorPool  ------------|-----------> upb_symtab____________________ | 
|  | |                | (message types)          \ | 
|  | |                v                           \ | 
|  | Descriptor   ---------------|-----------> upb_msgdef         (enum types)| | 
|  | |--> msgclass              |                |   ^                       | | 
|  | |    (dynamically built)   |                |   | (submsg fields)       | | 
|  | |--> MessageLayout         |                |   |                       / | 
|  | |--------------------------|> decoder method|   |                      / | 
|  | \--------------------------|> serialize     |   |                     / | 
|  | |  handlers      v   |                    / | 
|  | FieldDescriptor  -----------|-----------> upb_fielddef               / | 
|  | |                    |                  / | 
|  | |                    v (enum fields)   / | 
|  | EnumDescriptor  ------------|-----------> upb_enumdef  <----------' | 
|  | | | 
|  | | | 
|  | ^               |               \___/ | 
|  | `---------------|-----------------'    (get_def_obj map) | 
|  | */ | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Ruby class structure definitions. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | struct DescriptorPool { | 
|  | upb_symtab* symtab; | 
|  | }; | 
|  |  | 
|  | struct Descriptor { | 
|  | const upb_msgdef* msgdef; | 
|  | MessageLayout* layout; | 
|  | VALUE klass;  // begins as nil | 
|  | const upb_handlers* fill_handlers; | 
|  | const upb_pbdecodermethod* fill_method; | 
|  | const upb_json_parsermethod* json_fill_method; | 
|  | const upb_handlers* pb_serialize_handlers; | 
|  | const upb_handlers* json_serialize_handlers; | 
|  | const upb_handlers* json_serialize_handlers_preserve; | 
|  | }; | 
|  |  | 
|  | struct FileDescriptor { | 
|  | const upb_filedef* filedef; | 
|  | }; | 
|  |  | 
|  | struct FieldDescriptor { | 
|  | const upb_fielddef* fielddef; | 
|  | }; | 
|  |  | 
|  | struct OneofDescriptor { | 
|  | const upb_oneofdef* oneofdef; | 
|  | }; | 
|  |  | 
|  | struct EnumDescriptor { | 
|  | const upb_enumdef* enumdef; | 
|  | VALUE module;  // begins as nil | 
|  | }; | 
|  |  | 
|  | struct MessageBuilderContext { | 
|  | VALUE descriptor; | 
|  | VALUE builder; | 
|  | }; | 
|  |  | 
|  | struct OneofBuilderContext { | 
|  | VALUE descriptor; | 
|  | VALUE builder; | 
|  | }; | 
|  |  | 
|  | struct EnumBuilderContext { | 
|  | VALUE enumdesc; | 
|  | }; | 
|  |  | 
|  | struct FileBuilderContext { | 
|  | VALUE pending_list; | 
|  | VALUE file_descriptor; | 
|  | VALUE builder; | 
|  | }; | 
|  |  | 
|  | struct Builder { | 
|  | VALUE pending_list; | 
|  | VALUE default_file_descriptor; | 
|  | upb_def** defs;  // used only while finalizing | 
|  | }; | 
|  |  | 
|  | extern VALUE cDescriptorPool; | 
|  | extern VALUE cDescriptor; | 
|  | extern VALUE cFileDescriptor; | 
|  | extern VALUE cFieldDescriptor; | 
|  | extern VALUE cEnumDescriptor; | 
|  | extern VALUE cMessageBuilderContext; | 
|  | extern VALUE cOneofBuilderContext; | 
|  | extern VALUE cEnumBuilderContext; | 
|  | extern VALUE cFileBuilderContext; | 
|  | extern VALUE cBuilder; | 
|  |  | 
|  | extern VALUE cError; | 
|  | extern VALUE cParseError; | 
|  | extern VALUE cTypeError; | 
|  |  | 
|  | // We forward-declare all of the Ruby method implementations here because we | 
|  | // sometimes call the methods directly across .c files, rather than going | 
|  | // through Ruby's method dispatching (e.g. during message parse). It's cleaner | 
|  | // to keep the list of object methods together than to split them between | 
|  | // static-in-file definitions and header declarations. | 
|  |  | 
|  | void DescriptorPool_mark(void* _self); | 
|  | void DescriptorPool_free(void* _self); | 
|  | VALUE DescriptorPool_alloc(VALUE klass); | 
|  | void DescriptorPool_register(VALUE module); | 
|  | DescriptorPool* ruby_to_DescriptorPool(VALUE value); | 
|  | VALUE DescriptorPool_add(VALUE _self, VALUE def); | 
|  | VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE DescriptorPool_lookup(VALUE _self, VALUE name); | 
|  | VALUE DescriptorPool_generated_pool(VALUE _self); | 
|  |  | 
|  | void Descriptor_mark(void* _self); | 
|  | void Descriptor_free(void* _self); | 
|  | VALUE Descriptor_alloc(VALUE klass); | 
|  | void Descriptor_register(VALUE module); | 
|  | Descriptor* ruby_to_Descriptor(VALUE value); | 
|  | VALUE Descriptor_initialize(VALUE _self, VALUE file_descriptor_rb); | 
|  | VALUE Descriptor_name(VALUE _self); | 
|  | VALUE Descriptor_name_set(VALUE _self, VALUE str); | 
|  | VALUE Descriptor_each(VALUE _self); | 
|  | VALUE Descriptor_lookup(VALUE _self, VALUE name); | 
|  | VALUE Descriptor_add_field(VALUE _self, VALUE obj); | 
|  | VALUE Descriptor_add_oneof(VALUE _self, VALUE obj); | 
|  | VALUE Descriptor_each_oneof(VALUE _self); | 
|  | VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name); | 
|  | VALUE Descriptor_msgclass(VALUE _self); | 
|  | VALUE Descriptor_file_descriptor(VALUE _self); | 
|  | extern const rb_data_type_t _Descriptor_type; | 
|  |  | 
|  | void FileDescriptor_mark(void* _self); | 
|  | void FileDescriptor_free(void* _self); | 
|  | VALUE FileDescriptor_alloc(VALUE klass); | 
|  | void FileDescriptor_register(VALUE module); | 
|  | FileDescriptor* ruby_to_FileDescriptor(VALUE value); | 
|  | VALUE FileDescriptor_initialize(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE FileDescriptor_name(VALUE _self); | 
|  | VALUE FileDescriptor_syntax(VALUE _self); | 
|  | VALUE FileDescriptor_syntax_set(VALUE _self, VALUE syntax); | 
|  |  | 
|  | void FieldDescriptor_mark(void* _self); | 
|  | void FieldDescriptor_free(void* _self); | 
|  | VALUE FieldDescriptor_alloc(VALUE klass); | 
|  | void FieldDescriptor_register(VALUE module); | 
|  | FieldDescriptor* ruby_to_FieldDescriptor(VALUE value); | 
|  | VALUE FieldDescriptor_name(VALUE _self); | 
|  | VALUE FieldDescriptor_name_set(VALUE _self, VALUE str); | 
|  | VALUE FieldDescriptor_type(VALUE _self); | 
|  | VALUE FieldDescriptor_type_set(VALUE _self, VALUE type); | 
|  | VALUE FieldDescriptor_default(VALUE _self); | 
|  | VALUE FieldDescriptor_default_set(VALUE _self, VALUE default_value); | 
|  | VALUE FieldDescriptor_label(VALUE _self); | 
|  | VALUE FieldDescriptor_label_set(VALUE _self, VALUE label); | 
|  | VALUE FieldDescriptor_number(VALUE _self); | 
|  | VALUE FieldDescriptor_number_set(VALUE _self, VALUE number); | 
|  | VALUE FieldDescriptor_submsg_name(VALUE _self); | 
|  | VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value); | 
|  | VALUE FieldDescriptor_subtype(VALUE _self); | 
|  | VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb); | 
|  | VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb); | 
|  | VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb); | 
|  | VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value); | 
|  | upb_fieldtype_t ruby_to_fieldtype(VALUE type); | 
|  | VALUE fieldtype_to_ruby(upb_fieldtype_t type); | 
|  |  | 
|  | void OneofDescriptor_mark(void* _self); | 
|  | void OneofDescriptor_free(void* _self); | 
|  | VALUE OneofDescriptor_alloc(VALUE klass); | 
|  | void OneofDescriptor_register(VALUE module); | 
|  | OneofDescriptor* ruby_to_OneofDescriptor(VALUE value); | 
|  | VALUE OneofDescriptor_name(VALUE _self); | 
|  | VALUE OneofDescriptor_name_set(VALUE _self, VALUE value); | 
|  | VALUE OneofDescriptor_add_field(VALUE _self, VALUE field); | 
|  | VALUE OneofDescriptor_each(VALUE _self, VALUE field); | 
|  |  | 
|  | void EnumDescriptor_mark(void* _self); | 
|  | void EnumDescriptor_free(void* _self); | 
|  | VALUE EnumDescriptor_alloc(VALUE klass); | 
|  | void EnumDescriptor_register(VALUE module); | 
|  | EnumDescriptor* ruby_to_EnumDescriptor(VALUE value); | 
|  | VALUE EnumDescriptor_initialize(VALUE _self, VALUE file_descriptor_rb); | 
|  | VALUE EnumDescriptor_file_descriptor(VALUE _self); | 
|  | VALUE EnumDescriptor_name(VALUE _self); | 
|  | VALUE EnumDescriptor_name_set(VALUE _self, VALUE str); | 
|  | VALUE EnumDescriptor_add_value(VALUE _self, VALUE name, VALUE number); | 
|  | VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name); | 
|  | VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number); | 
|  | VALUE EnumDescriptor_each(VALUE _self); | 
|  | VALUE EnumDescriptor_enummodule(VALUE _self); | 
|  | extern const rb_data_type_t _EnumDescriptor_type; | 
|  |  | 
|  | void MessageBuilderContext_mark(void* _self); | 
|  | void MessageBuilderContext_free(void* _self); | 
|  | VALUE MessageBuilderContext_alloc(VALUE klass); | 
|  | void MessageBuilderContext_register(VALUE module); | 
|  | MessageBuilderContext* ruby_to_MessageBuilderContext(VALUE value); | 
|  | VALUE MessageBuilderContext_initialize(VALUE _self, | 
|  | VALUE descriptor, | 
|  | VALUE builder); | 
|  | VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name); | 
|  |  | 
|  | void OneofBuilderContext_mark(void* _self); | 
|  | void OneofBuilderContext_free(void* _self); | 
|  | VALUE OneofBuilderContext_alloc(VALUE klass); | 
|  | void OneofBuilderContext_register(VALUE module); | 
|  | OneofBuilderContext* ruby_to_OneofBuilderContext(VALUE value); | 
|  | VALUE OneofBuilderContext_initialize(VALUE _self, | 
|  | VALUE descriptor, | 
|  | VALUE builder); | 
|  | VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self); | 
|  |  | 
|  | void EnumBuilderContext_mark(void* _self); | 
|  | void EnumBuilderContext_free(void* _self); | 
|  | VALUE EnumBuilderContext_alloc(VALUE klass); | 
|  | void EnumBuilderContext_register(VALUE module); | 
|  | EnumBuilderContext* ruby_to_EnumBuilderContext(VALUE value); | 
|  | VALUE EnumBuilderContext_initialize(VALUE _self, VALUE enumdesc); | 
|  | VALUE EnumBuilderContext_value(VALUE _self, VALUE name, VALUE number); | 
|  |  | 
|  | void FileBuilderContext_mark(void* _self); | 
|  | void FileBuilderContext_free(void* _self); | 
|  | VALUE FileBuilderContext_alloc(VALUE klass); | 
|  | void FileBuilderContext_register(VALUE module); | 
|  | VALUE FileBuilderContext_initialize(VALUE _self, VALUE file_descriptor, | 
|  | VALUE builder); | 
|  | VALUE FileBuilderContext_add_message(VALUE _self, VALUE name); | 
|  | VALUE FileBuilderContext_add_enum(VALUE _self, VALUE name); | 
|  | VALUE FileBuilderContext_pending_descriptors(VALUE _self); | 
|  |  | 
|  | void Builder_mark(void* _self); | 
|  | void Builder_free(void* _self); | 
|  | VALUE Builder_alloc(VALUE klass); | 
|  | void Builder_register(VALUE module); | 
|  | Builder* ruby_to_Builder(VALUE value); | 
|  | VALUE Builder_initialize(VALUE _self); | 
|  | VALUE Builder_add_file(int argc, VALUE *argv, VALUE _self); | 
|  | VALUE Builder_add_message(VALUE _self, VALUE name); | 
|  | VALUE Builder_add_enum(VALUE _self, VALUE name); | 
|  | VALUE Builder_finalize_to_pool(VALUE _self, VALUE pool_rb); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Native slot storage abstraction. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t) | 
|  |  | 
|  | size_t native_slot_size(upb_fieldtype_t type); | 
|  | void native_slot_set(upb_fieldtype_t type, | 
|  | VALUE type_class, | 
|  | void* memory, | 
|  | VALUE value); | 
|  | // Atomically (with respect to Ruby VM calls) either update the value and set a | 
|  | // oneof case, or do neither. If |case_memory| is null, then no case value is | 
|  | // set. | 
|  | void native_slot_set_value_and_case(upb_fieldtype_t type, | 
|  | VALUE type_class, | 
|  | void* memory, | 
|  | VALUE value, | 
|  | uint32_t* case_memory, | 
|  | uint32_t case_number); | 
|  | VALUE native_slot_get(upb_fieldtype_t type, | 
|  | VALUE type_class, | 
|  | const void* memory); | 
|  | void native_slot_init(upb_fieldtype_t type, void* memory); | 
|  | void native_slot_mark(upb_fieldtype_t type, void* memory); | 
|  | void native_slot_dup(upb_fieldtype_t type, void* to, void* from); | 
|  | void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from); | 
|  | bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2); | 
|  |  | 
|  | VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value); | 
|  | void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value); | 
|  |  | 
|  | extern rb_encoding* kRubyStringUtf8Encoding; | 
|  | extern rb_encoding* kRubyStringASCIIEncoding; | 
|  | extern rb_encoding* kRubyString8bitEncoding; | 
|  |  | 
|  | VALUE field_type_class(const upb_fielddef* field); | 
|  |  | 
|  | #define MAP_KEY_FIELD 1 | 
|  | #define MAP_VALUE_FIELD 2 | 
|  |  | 
|  | // Oneof case slot value to indicate that no oneof case is set. The value `0` is | 
|  | // safe because field numbers are used as case identifiers, and no field can | 
|  | // have a number of 0. | 
|  | #define ONEOF_CASE_NONE 0 | 
|  |  | 
|  | // These operate on a map field (i.e., a repeated field of submessages whose | 
|  | // submessage type is a map-entry msgdef). | 
|  | bool is_map_field(const upb_fielddef* field); | 
|  | const upb_fielddef* map_field_key(const upb_fielddef* field); | 
|  | const upb_fielddef* map_field_value(const upb_fielddef* field); | 
|  |  | 
|  | // These operate on a map-entry msgdef. | 
|  | const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); | 
|  | const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Repeated field container type. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | upb_fieldtype_t field_type; | 
|  | VALUE field_type_class; | 
|  | void* elements; | 
|  | int size; | 
|  | int capacity; | 
|  | } RepeatedField; | 
|  |  | 
|  | void RepeatedField_mark(void* self); | 
|  | void RepeatedField_free(void* self); | 
|  | VALUE RepeatedField_alloc(VALUE klass); | 
|  | VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self); | 
|  | void RepeatedField_register(VALUE module); | 
|  |  | 
|  | extern const rb_data_type_t RepeatedField_type; | 
|  | extern VALUE cRepeatedField; | 
|  |  | 
|  | RepeatedField* ruby_to_RepeatedField(VALUE value); | 
|  |  | 
|  | VALUE RepeatedField_each(VALUE _self); | 
|  | VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self); | 
|  | void* RepeatedField_index_native(VALUE _self, int index); | 
|  | int RepeatedField_size(VALUE _self); | 
|  | VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val); | 
|  | void RepeatedField_reserve(RepeatedField* self, int new_size); | 
|  | VALUE RepeatedField_push(VALUE _self, VALUE val); | 
|  | void RepeatedField_push_native(VALUE _self, void* data); | 
|  | VALUE RepeatedField_pop_one(VALUE _self); | 
|  | VALUE RepeatedField_insert(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE RepeatedField_replace(VALUE _self, VALUE list); | 
|  | VALUE RepeatedField_clear(VALUE _self); | 
|  | VALUE RepeatedField_length(VALUE _self); | 
|  | VALUE RepeatedField_dup(VALUE _self); | 
|  | VALUE RepeatedField_deep_copy(VALUE _self); | 
|  | VALUE RepeatedField_to_ary(VALUE _self); | 
|  | VALUE RepeatedField_eq(VALUE _self, VALUE _other); | 
|  | VALUE RepeatedField_hash(VALUE _self); | 
|  | VALUE RepeatedField_inspect(VALUE _self); | 
|  | VALUE RepeatedField_plus(VALUE _self, VALUE list); | 
|  |  | 
|  | // Defined in repeated_field.c; also used by Map. | 
|  | void validate_type_class(upb_fieldtype_t type, VALUE klass); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Map container type. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | upb_fieldtype_t key_type; | 
|  | upb_fieldtype_t value_type; | 
|  | VALUE value_type_class; | 
|  | VALUE parse_frame; | 
|  | upb_strtable table; | 
|  | } Map; | 
|  |  | 
|  | void Map_mark(void* self); | 
|  | void Map_free(void* self); | 
|  | VALUE Map_alloc(VALUE klass); | 
|  | VALUE Map_init(int argc, VALUE* argv, VALUE self); | 
|  | void Map_register(VALUE module); | 
|  | VALUE Map_set_frame(VALUE self, VALUE val); | 
|  |  | 
|  | extern const rb_data_type_t Map_type; | 
|  | extern VALUE cMap; | 
|  |  | 
|  | Map* ruby_to_Map(VALUE value); | 
|  |  | 
|  | VALUE Map_each(VALUE _self); | 
|  | VALUE Map_keys(VALUE _self); | 
|  | VALUE Map_values(VALUE _self); | 
|  | VALUE Map_index(VALUE _self, VALUE key); | 
|  | VALUE Map_index_set(VALUE _self, VALUE key, VALUE value); | 
|  | VALUE Map_has_key(VALUE _self, VALUE key); | 
|  | VALUE Map_delete(VALUE _self, VALUE key); | 
|  | VALUE Map_clear(VALUE _self); | 
|  | VALUE Map_length(VALUE _self); | 
|  | VALUE Map_dup(VALUE _self); | 
|  | VALUE Map_deep_copy(VALUE _self); | 
|  | VALUE Map_eq(VALUE _self, VALUE _other); | 
|  | VALUE Map_hash(VALUE _self); | 
|  | VALUE Map_to_h(VALUE _self); | 
|  | VALUE Map_inspect(VALUE _self); | 
|  | VALUE Map_merge(VALUE _self, VALUE hashmap); | 
|  | VALUE Map_merge_into_self(VALUE _self, VALUE hashmap); | 
|  |  | 
|  | typedef struct { | 
|  | Map* self; | 
|  | upb_strtable_iter it; | 
|  | } Map_iter; | 
|  |  | 
|  | void Map_begin(VALUE _self, Map_iter* iter); | 
|  | void Map_next(Map_iter* iter); | 
|  | bool Map_done(Map_iter* iter); | 
|  | VALUE Map_iter_key(Map_iter* iter); | 
|  | VALUE Map_iter_value(Map_iter* iter); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Message layout / storage. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | #define MESSAGE_FIELD_NO_CASE ((size_t)-1) | 
|  | #define MESSAGE_FIELD_NO_HASBIT ((size_t)-1) | 
|  |  | 
|  | struct MessageField { | 
|  | size_t offset; | 
|  | size_t case_offset;  // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. | 
|  | size_t hasbit; | 
|  | }; | 
|  |  | 
|  | struct MessageLayout { | 
|  | const upb_msgdef* msgdef; | 
|  | MessageField* fields; | 
|  | size_t size; | 
|  | }; | 
|  |  | 
|  | MessageLayout* create_layout(const upb_msgdef* msgdef); | 
|  | void free_layout(MessageLayout* layout); | 
|  | bool field_contains_hasbit(MessageLayout* layout, | 
|  | const upb_fielddef* field); | 
|  | VALUE layout_get_default(const upb_fielddef* field); | 
|  | VALUE layout_get(MessageLayout* layout, | 
|  | const void* storage, | 
|  | const upb_fielddef* field); | 
|  | void layout_set(MessageLayout* layout, | 
|  | void* storage, | 
|  | const upb_fielddef* field, | 
|  | VALUE val); | 
|  | VALUE layout_has(MessageLayout* layout, | 
|  | const void* storage, | 
|  | const upb_fielddef* field); | 
|  | void layout_clear(MessageLayout* layout, | 
|  | const void* storage, | 
|  | const upb_fielddef* field); | 
|  | void layout_init(MessageLayout* layout, void* storage); | 
|  | void layout_mark(MessageLayout* layout, void* storage); | 
|  | void layout_dup(MessageLayout* layout, void* to, void* from); | 
|  | void layout_deep_copy(MessageLayout* layout, void* to, void* from); | 
|  | VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2); | 
|  | VALUE layout_hash(MessageLayout* layout, void* storage); | 
|  | VALUE layout_inspect(MessageLayout* layout, void* storage); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Message class creation. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | // This should probably be factored into a common upb component. | 
|  |  | 
|  | typedef struct { | 
|  | upb_byteshandler handler; | 
|  | upb_bytessink sink; | 
|  | char *ptr; | 
|  | size_t len, size; | 
|  | } stringsink; | 
|  |  | 
|  | void stringsink_uninit(stringsink *sink); | 
|  |  | 
|  | struct MessageHeader { | 
|  | Descriptor* descriptor;      // kept alive by self.class.descriptor reference. | 
|  | stringsink* unknown_fields;  // store unknown fields in decoding. | 
|  | // Data comes after this. | 
|  | }; | 
|  |  | 
|  | extern rb_data_type_t Message_type; | 
|  |  | 
|  | VALUE build_class_from_descriptor(Descriptor* descriptor); | 
|  | void* Message_data(void* msg); | 
|  | void Message_mark(void* self); | 
|  | void Message_free(void* self); | 
|  | VALUE Message_alloc(VALUE klass); | 
|  | VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE Message_initialize(int argc, VALUE* argv, VALUE _self); | 
|  | VALUE Message_dup(VALUE _self); | 
|  | VALUE Message_deep_copy(VALUE _self); | 
|  | VALUE Message_eq(VALUE _self, VALUE _other); | 
|  | VALUE Message_hash(VALUE _self); | 
|  | VALUE Message_inspect(VALUE _self); | 
|  | VALUE Message_to_h(VALUE _self); | 
|  | VALUE Message_index(VALUE _self, VALUE field_name); | 
|  | VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value); | 
|  | VALUE Message_descriptor(VALUE klass); | 
|  | VALUE Message_decode(VALUE klass, VALUE data); | 
|  | VALUE Message_encode(VALUE klass, VALUE msg_rb); | 
|  | VALUE Message_decode_json(VALUE klass, VALUE data); | 
|  | VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass); | 
|  |  | 
|  | VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb); | 
|  | VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj); | 
|  |  | 
|  | VALUE build_module_from_enumdesc(EnumDescriptor* enumdef); | 
|  | VALUE enum_lookup(VALUE self, VALUE number); | 
|  | VALUE enum_resolve(VALUE self, VALUE sym); | 
|  |  | 
|  | const upb_pbdecodermethod *new_fillmsg_decodermethod( | 
|  | Descriptor* descriptor, const void *owner); | 
|  |  | 
|  | // Maximum depth allowed during encoding, to avoid stack overflows due to | 
|  | // cycles. | 
|  | #define ENCODE_MAX_NESTING 63 | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor | 
|  | // instances. | 
|  | // ----------------------------------------------------------------------------- | 
|  | void add_def_obj(const void* def, VALUE value); | 
|  | VALUE get_def_obj(const void* def); | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Utilities. | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void check_upb_status(const upb_status* status, const char* msg); | 
|  |  | 
|  | #define CHECK_UPB(code, msg) do {                                             \ | 
|  | upb_status status = UPB_STATUS_INIT;                                      \ | 
|  | code;                                                                     \ | 
|  | check_upb_status(&status, msg);                                           \ | 
|  | } while (0) | 
|  |  | 
|  | extern ID descriptor_instancevar_interned; | 
|  |  | 
|  | #endif  // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ |