• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Protocol Buffers - Google's data interchange format
2# Copyright 2022 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
8module Google
9  module Protobuf
10    class FFI
11      extend ::FFI::Library
12      # Workaround for Bazel's use of symlinks + JRuby's __FILE__ and `caller`
13      # that resolves them.
14      if ENV['BAZEL'] == 'true'
15        ffi_lib ::FFI::Compiler::Loader.find 'protobuf_c_ffi', ENV['PWD']
16      else
17        ffi_lib ::FFI::Compiler::Loader.find 'protobuf_c_ffi'
18      end
19
20      ## Map
21      Upb_Map_Begin = -1
22
23      ## Encoding Status
24      Upb_Status_MaxMessage = 511
25      Upb_Encode_Deterministic = 1
26      Upb_Encode_SkipUnknown = 2
27
28      ## JSON Encoding options
29      # When set, emits 0/default values.  TODO: proto3 only?
30      Upb_JsonEncode_EmitDefaults = 1
31      # When set, use normal (snake_case) field names instead of JSON (camelCase) names.
32      Upb_JsonEncode_UseProtoNames = 2
33      # When set, emits enums as their integer values instead of as their names.
34      Upb_JsonEncode_FormatEnumsAsIntegers = 4
35
36      ## JSON Decoding options
37      Upb_JsonDecode_IgnoreUnknown = 1
38
39      ## JSON Decoding results
40      Upb_JsonDecodeResult_Ok = 0
41      Upb_JsonDecodeResult_OkWithEmptyStringNumerics = 1
42      Upb_JsonDecodeResult_Error = 2
43
44      typedef :pointer, :Array
45      typedef :pointer, :DefPool
46      typedef :pointer, :EnumValueDef
47      typedef :pointer, :ExtensionRegistry
48      typedef :pointer, :FieldDefPointer
49      typedef :pointer, :FileDef
50      typedef :pointer, :FileDescriptorProto
51      typedef :pointer, :Map
52      typedef :pointer, :Message    # Instances of a message
53      typedef :pointer, :OneofDefPointer
54      typedef :pointer, :binary_string
55      if ::FFI::Platform::ARCH == "aarch64"
56        typedef :u_int8_t, :uint8_t
57        typedef :u_int16_t, :uint16_t
58        typedef :u_int32_t, :uint32_t
59        typedef :u_int64_t, :uint64_t
60      end
61
62      FieldType = enum(
63        :double, 1,
64        :float,
65        :int64,
66        :uint64,
67        :int32,
68        :fixed64,
69        :fixed32,
70        :bool,
71        :string,
72        :group,
73        :message,
74        :bytes,
75        :uint32,
76        :enum,
77        :sfixed32,
78        :sfixed64,
79        :sint32,
80        :sint64
81      )
82
83      CType = enum(
84        :bool, 1,
85        :float,
86        :int32,
87        :uint32,
88        :enum,
89        :message,
90        :double,
91        :int64,
92        :uint64,
93        :string,
94        :bytes
95      )
96
97      Label = enum(
98        :optional, 1,
99        :required,
100        :repeated
101      )
102
103      # All the different kind of well known type messages. For simplicity of check,
104      # number wrappers and string wrappers are grouped together. Make sure the
105      # order and merber of these groups are not changed.
106
107      WellKnown = enum(
108        :Unspecified,
109        :Any,
110        :FieldMask,
111        :Duration,
112        :Timestamp,
113        # number wrappers
114        :DoubleValue,
115        :FloatValue,
116        :Int64Value,
117        :UInt64Value,
118        :Int32Value,
119        :UInt32Value,
120        # string wrappers
121        :StringValue,
122        :BytesValue,
123        :BoolValue,
124        :Value,
125        :ListValue,
126        :Struct
127      )
128
129      DecodeStatus = enum(
130        :Ok,
131        :Malformed,         # Wire format was corrupt
132        :OutOfMemory,       # Arena alloc failed
133        :BadUtf8,           # String field had bad UTF-8
134        :MaxDepthExceeded,  # Exceeded UPB_DECODE_MAXDEPTH
135
136        # CheckRequired failed, but the parse otherwise succeeded.
137        :MissingRequired,
138      )
139
140      EncodeStatus = enum(
141        :Ok,
142        :OutOfMemory,       # Arena alloc failed
143        :MaxDepthExceeded,  # Exceeded UPB_DECODE_MAXDEPTH
144
145        # CheckRequired failed, but the parse otherwise succeeded.
146        :MissingRequired,
147      )
148
149      class StringView < ::FFI::Struct
150        layout :data, :pointer,
151               :size, :size_t
152      end
153
154      class MiniTable < ::FFI::Struct
155        layout :subs, :pointer,
156               :fields, :pointer,
157               :size, :uint16_t,
158               :field_count, :uint16_t,
159               :ext, :uint8_t,  # upb_ExtMode, declared as uint8_t so sizeof(ext) == 1
160               :dense_below, :uint8_t,
161               :table_mask, :uint8_t,
162               :required_count, :uint8_t  # Required fields have the lowest hasbits.
163        # To statically initialize the tables of variable length, we need a flexible
164        # array member, and we need to compile in gnu99 mode (constant initialization
165        # of flexible array members is a GNU extension, not in C99 unfortunately. */
166        #       _upb_FastTable_Entry fasttable[];
167      end
168
169      class Status < ::FFI::Struct
170        layout :ok, :bool,
171               :msg, [:char, Upb_Status_MaxMessage]
172
173        def initialize
174          super
175          FFI.clear self
176        end
177      end
178
179      class MessageValue < ::FFI::Union
180        layout :bool_val, :bool,
181               :float_val, :float,
182               :double_val, :double,
183               :int32_val, :int32_t,
184               :int64_val, :int64_t,
185               :uint32_val, :uint32_t,
186               :uint64_val,:uint64_t,
187               :map_val, :pointer,
188               :msg_val, :pointer,
189               :array_val,:pointer,
190               :str_val, StringView
191      end
192
193      Upb_Message_Begin = -1
194
195      class MutableMessageValue < ::FFI::Union
196        layout :map, :Map,
197               :msg, :Message,
198               :array, :Array
199      end
200
201      # Status
202      attach_function :clear,                 :upb_Status_Clear, [Status.by_ref], :void
203      attach_function :error_message,         :upb_Status_ErrorMessage, [Status.by_ref], :string
204
205      # Generic
206      attach_function :memcmp, [:pointer, :pointer, :size_t], :int
207      attach_function :memcpy, [:pointer, :pointer, :size_t], :int
208
209      # Alternatives to pre-processor macros
210      def self.decode_max_depth(i)
211        i << 16
212      end
213    end
214  end
215end
216