1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2014 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ 9 #define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ 10 11 // Ruby 3+ defines NDEBUG itself, see: https://bugs.ruby-lang.org/issues/18777 12 #ifdef NDEBUG 13 #include <ruby.h> 14 #else 15 #include <ruby.h> 16 #undef NDEBUG 17 #endif 18 19 #include <ruby/version.h> 20 21 #if RUBY_API_VERSION_CODE < 20700 22 #error Protobuf requires Ruby >= 2.7 23 #endif 24 25 #include <assert.h> // Must be included after the NDEBUG logic above. 26 #include <ruby/encoding.h> 27 #include <ruby/vm.h> 28 29 #include "defs.h" 30 #include "ruby-upb.h" 31 32 // These operate on a map field (i.e., a repeated field of submessages whose 33 // submessage type is a map-entry msgdef). 34 const upb_FieldDef* map_field_key(const upb_FieldDef* field); 35 const upb_FieldDef* map_field_value(const upb_FieldDef* field); 36 37 // ----------------------------------------------------------------------------- 38 // Arena 39 // ----------------------------------------------------------------------------- 40 41 // A Ruby object that wraps an underlying upb_Arena. Any objects that are 42 // allocated from this arena should reference the Arena in rb_gc_mark(), to 43 // ensure that the object's underlying memory outlives any Ruby object that can 44 // reach it. 45 46 VALUE Arena_new(); 47 upb_Arena* Arena_get(VALUE arena); 48 49 // Fuses this arena to another, throwing a Ruby exception if this is not 50 // possible. 51 void Arena_fuse(VALUE arena, upb_Arena* other); 52 53 // ----------------------------------------------------------------------------- 54 // ObjectCache 55 // ----------------------------------------------------------------------------- 56 57 // Global object cache from upb array/map/message/symtab to wrapper object. 58 // 59 // This is a conceptually "weak" cache, in that it does not prevent "val" from 60 // being collected (though in Ruby <2.7 is it effectively strong, due to 61 // implementation limitations). 62 63 // Tries to add a new entry to the cache, returning the newly installed value or 64 // the pre-existing entry. 65 VALUE ObjectCache_TryAdd(const void* key, VALUE val); 66 67 // Returns the cached object for this key, if any. Otherwise returns Qnil. 68 VALUE ObjectCache_Get(const void* key); 69 70 // ----------------------------------------------------------------------------- 71 // StringBuilder, for inspect 72 // ----------------------------------------------------------------------------- 73 74 struct StringBuilder; 75 typedef struct StringBuilder StringBuilder; 76 77 StringBuilder* StringBuilder_New(); 78 void StringBuilder_Free(StringBuilder* b); 79 void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...); 80 VALUE StringBuilder_ToRubyString(StringBuilder* b); 81 82 void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val, 83 TypeInfo info); 84 85 // ----------------------------------------------------------------------------- 86 // Utilities. 87 // ----------------------------------------------------------------------------- 88 89 extern VALUE cTypeError; 90 91 #ifdef NDEBUG 92 #define PBRUBY_ASSERT(expr) \ 93 do { \ 94 } while (false && (expr)) 95 #else 96 #define PBRUBY_ASSERT(expr) \ 97 if (!(expr)) \ 98 rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr) 99 #endif 100 101 // Raises a Ruby error if val is frozen in Ruby or upb_frozen is true. 102 void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen); 103 104 #define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y)) 105 106 #define UPB_UNUSED(var) (void)var 107 108 #endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ 109