• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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