google-protobuf 3.22.0 → 3.25.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +23 -70
- data/ext/google/protobuf_c/convert.h +3 -28
- data/ext/google/protobuf_c/defs.c +175 -52
- data/ext/google/protobuf_c/defs.h +3 -28
- data/ext/google/protobuf_c/extconf.rb +2 -1
- data/ext/google/protobuf_c/glue.c +56 -0
- data/ext/google/protobuf_c/map.c +27 -28
- data/ext/google/protobuf_c/map.h +6 -28
- data/ext/google/protobuf_c/message.c +83 -83
- data/ext/google/protobuf_c/message.h +10 -28
- data/ext/google/protobuf_c/protobuf.c +39 -176
- data/ext/google/protobuf_c/protobuf.h +24 -32
- data/ext/google/protobuf_c/repeated_field.c +28 -29
- data/ext/google/protobuf_c/repeated_field.h +6 -28
- data/ext/google/protobuf_c/ruby-upb.c +2982 -2494
- data/ext/google/protobuf_c/ruby-upb.h +5838 -3467
- data/ext/google/protobuf_c/shared_convert.c +64 -0
- data/ext/google/protobuf_c/shared_convert.h +26 -0
- data/ext/google/protobuf_c/shared_message.c +65 -0
- data/ext/google/protobuf_c/shared_message.h +25 -0
- data/ext/google/protobuf_c/wrap_memcpy.c +3 -26
- data/lib/google/protobuf/any_pb.rb +24 -5
- data/lib/google/protobuf/api_pb.rb +26 -23
- data/lib/google/protobuf/descriptor_pb.rb +40 -252
- data/lib/google/protobuf/duration_pb.rb +24 -5
- data/lib/google/protobuf/empty_pb.rb +24 -3
- data/lib/google/protobuf/ffi/descriptor.rb +165 -0
- data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
- data/lib/google/protobuf/ffi/ffi.rb +213 -0
- data/lib/google/protobuf/ffi/field_descriptor.rb +319 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
- data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
- data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
- data/lib/google/protobuf/ffi/map.rb +407 -0
- data/lib/google/protobuf/ffi/message.rb +662 -0
- data/lib/google/protobuf/ffi/object_cache.rb +30 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +383 -0
- data/lib/google/protobuf/field_mask_pb.rb +24 -4
- data/lib/google/protobuf/message_exts.rb +3 -26
- data/lib/google/protobuf/object_cache.rb +97 -0
- data/lib/google/protobuf/plugin_pb.rb +25 -28
- data/lib/google/protobuf/repeated_field.rb +3 -26
- data/lib/google/protobuf/source_context_pb.rb +24 -4
- data/lib/google/protobuf/struct_pb.rb +24 -20
- data/lib/google/protobuf/timestamp_pb.rb +24 -5
- data/lib/google/protobuf/type_pb.rb +26 -68
- data/lib/google/protobuf/well_known_types.rb +5 -34
- data/lib/google/protobuf/wrappers_pb.rb +24 -28
- data/lib/google/protobuf.rb +27 -45
- data/lib/google/protobuf_ffi.rb +50 -0
- data/lib/google/protobuf_native.rb +20 -0
- data/lib/google/tasks/ffi.rake +102 -0
- metadata +72 -4
@@ -0,0 +1,171 @@
|
|
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
|
+
|
8
|
+
module Google
|
9
|
+
module Protobuf
|
10
|
+
class EnumDescriptor
|
11
|
+
attr :descriptor_pool, :enum_def
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
# FFI Interface methods and setup
|
15
|
+
extend ::FFI::DataConverter
|
16
|
+
native_type ::FFI::Type::POINTER
|
17
|
+
|
18
|
+
class << self
|
19
|
+
prepend Google::Protobuf::Internal::TypeSafety
|
20
|
+
include Google::Protobuf::Internal::PointerHelper
|
21
|
+
|
22
|
+
# @param value [EnumDescriptor] EnumDescriptor to convert to an FFI native type
|
23
|
+
# @param _ [Object] Unused
|
24
|
+
def to_native(value, _)
|
25
|
+
value.instance_variable_get(:@enum_def) || ::FFI::Pointer::NULL
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @param enum_def [::FFI::Pointer] EnumDef pointer to be wrapped
|
30
|
+
# @param _ [Object] Unused
|
31
|
+
def from_native(enum_def, _)
|
32
|
+
return nil if enum_def.nil? or enum_def.null?
|
33
|
+
file_def = Google::Protobuf::FFI.get_message_file_def enum_def
|
34
|
+
descriptor_from_file_def(file_def, enum_def)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.new(*arguments, &block)
|
39
|
+
raise "Descriptor objects may not be created from Ruby."
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_descriptor
|
43
|
+
@descriptor_pool.send(:get_file_descriptor, Google::Protobuf::FFI.get_enum_file_descriptor(self))
|
44
|
+
end
|
45
|
+
|
46
|
+
def name
|
47
|
+
Google::Protobuf::FFI.get_enum_fullname(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
inspect
|
52
|
+
end
|
53
|
+
|
54
|
+
def inspect
|
55
|
+
"#{self.class.name}: #{name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def lookup_name(name)
|
59
|
+
self.class.send(:lookup_name, self, name)
|
60
|
+
end
|
61
|
+
|
62
|
+
def lookup_value(number)
|
63
|
+
self.class.send(:lookup_value, self, number)
|
64
|
+
end
|
65
|
+
|
66
|
+
def each &block
|
67
|
+
n = Google::Protobuf::FFI.enum_value_count(self)
|
68
|
+
0.upto(n - 1) do |i|
|
69
|
+
enum_value = Google::Protobuf::FFI.enum_value_by_index(self, i)
|
70
|
+
yield(Google::Protobuf::FFI.enum_name(enum_value).to_sym, Google::Protobuf::FFI.enum_number(enum_value))
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def enummodule
|
76
|
+
if @module.nil?
|
77
|
+
@module = build_enum_module
|
78
|
+
end
|
79
|
+
@module
|
80
|
+
end
|
81
|
+
|
82
|
+
def options
|
83
|
+
@options ||= begin
|
84
|
+
size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
|
85
|
+
temporary_arena = Google::Protobuf::FFI.create_arena
|
86
|
+
buffer = Google::Protobuf::FFI.enum_options(self, size_ptr, temporary_arena)
|
87
|
+
Google::Protobuf::EnumOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def initialize(enum_def, descriptor_pool)
|
94
|
+
@descriptor_pool = descriptor_pool
|
95
|
+
@enum_def = enum_def
|
96
|
+
@module = nil
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.private_constructor(enum_def, descriptor_pool)
|
100
|
+
instance = allocate
|
101
|
+
instance.send(:initialize, enum_def, descriptor_pool)
|
102
|
+
instance
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.lookup_value(enum_def, number)
|
106
|
+
enum_value = Google::Protobuf::FFI.enum_value_by_number(enum_def, number)
|
107
|
+
if enum_value.null?
|
108
|
+
nil
|
109
|
+
else
|
110
|
+
Google::Protobuf::FFI.enum_name(enum_value).to_sym
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.lookup_name(enum_def, name)
|
115
|
+
enum_value = Google::Protobuf::FFI.enum_value_by_name(enum_def, name.to_s, name.size)
|
116
|
+
if enum_value.null?
|
117
|
+
nil
|
118
|
+
else
|
119
|
+
Google::Protobuf::FFI.enum_number(enum_value)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def build_enum_module
|
124
|
+
descriptor = self
|
125
|
+
dynamic_module = Module.new do
|
126
|
+
@descriptor = descriptor
|
127
|
+
|
128
|
+
class << self
|
129
|
+
attr_accessor :descriptor
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.lookup(number)
|
133
|
+
descriptor.lookup_value number
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.resolve(name)
|
137
|
+
descriptor.lookup_name name
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
self.each do |name, value|
|
142
|
+
if name[0] < 'A' || name[0] > 'Z'
|
143
|
+
if name[0] >= 'a' and name[0] <= 'z'
|
144
|
+
name = name[0].upcase + name[1..-1] # auto capitalize
|
145
|
+
else
|
146
|
+
warn(
|
147
|
+
"Enum value '#{name}' does not start with an uppercase letter " +
|
148
|
+
"as is required for Ruby constants.")
|
149
|
+
next
|
150
|
+
end
|
151
|
+
end
|
152
|
+
dynamic_module.const_set(name.to_sym, value)
|
153
|
+
end
|
154
|
+
dynamic_module
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class FFI
|
159
|
+
# EnumDescriptor
|
160
|
+
attach_function :get_enum_file_descriptor, :upb_EnumDef_File, [EnumDescriptor], :FileDef
|
161
|
+
attach_function :enum_value_by_name, :upb_EnumDef_FindValueByNameWithSize,[EnumDescriptor, :string, :size_t], :EnumValueDef
|
162
|
+
attach_function :enum_value_by_number, :upb_EnumDef_FindValueByNumber, [EnumDescriptor, :int], :EnumValueDef
|
163
|
+
attach_function :get_enum_fullname, :upb_EnumDef_FullName, [EnumDescriptor], :string
|
164
|
+
attach_function :enum_options, :EnumDescriptor_serialized_options, [EnumDescriptor, :pointer, Internal::Arena], :pointer
|
165
|
+
attach_function :enum_value_by_index, :upb_EnumDef_Value, [EnumDescriptor, :int], :EnumValueDef
|
166
|
+
attach_function :enum_value_count, :upb_EnumDef_ValueCount, [EnumDescriptor], :int
|
167
|
+
attach_function :enum_name, :upb_EnumValueDef_Name, [:EnumValueDef], :string
|
168
|
+
attach_function :enum_number, :upb_EnumValueDef_Number, [:EnumValueDef], :int
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,213 @@
|
|
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
|
+
|
8
|
+
module 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 = 127
|
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
|
+
typedef :pointer, :Array
|
40
|
+
typedef :pointer, :DefPool
|
41
|
+
typedef :pointer, :EnumValueDef
|
42
|
+
typedef :pointer, :ExtensionRegistry
|
43
|
+
typedef :pointer, :FieldDefPointer
|
44
|
+
typedef :pointer, :FileDef
|
45
|
+
typedef :pointer, :FileDescriptorProto
|
46
|
+
typedef :pointer, :Map
|
47
|
+
typedef :pointer, :Message # Instances of a message
|
48
|
+
typedef :pointer, :OneofDefPointer
|
49
|
+
typedef :pointer, :binary_string
|
50
|
+
if ::FFI::Platform::ARCH == "aarch64"
|
51
|
+
typedef :u_int8_t, :uint8_t
|
52
|
+
typedef :u_int16_t, :uint16_t
|
53
|
+
typedef :u_int32_t, :uint32_t
|
54
|
+
typedef :u_int64_t, :uint64_t
|
55
|
+
end
|
56
|
+
|
57
|
+
FieldType = enum(
|
58
|
+
:double, 1,
|
59
|
+
:float,
|
60
|
+
:int64,
|
61
|
+
:uint64,
|
62
|
+
:int32,
|
63
|
+
:fixed64,
|
64
|
+
:fixed32,
|
65
|
+
:bool,
|
66
|
+
:string,
|
67
|
+
:group,
|
68
|
+
:message,
|
69
|
+
:bytes,
|
70
|
+
:uint32,
|
71
|
+
:enum,
|
72
|
+
:sfixed32,
|
73
|
+
:sfixed64,
|
74
|
+
:sint32,
|
75
|
+
:sint64
|
76
|
+
)
|
77
|
+
|
78
|
+
CType = enum(
|
79
|
+
:bool, 1,
|
80
|
+
:float,
|
81
|
+
:int32,
|
82
|
+
:uint32,
|
83
|
+
:enum,
|
84
|
+
:message,
|
85
|
+
:double,
|
86
|
+
:int64,
|
87
|
+
:uint64,
|
88
|
+
:string,
|
89
|
+
:bytes
|
90
|
+
)
|
91
|
+
|
92
|
+
Label = enum(
|
93
|
+
:optional, 1,
|
94
|
+
:required,
|
95
|
+
:repeated
|
96
|
+
)
|
97
|
+
|
98
|
+
Syntax = enum(
|
99
|
+
:Proto2, 2,
|
100
|
+
:Proto3
|
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
|
+
class MutableMessageValue < ::FFI::Union
|
194
|
+
layout :map, :Map,
|
195
|
+
:msg, :Message,
|
196
|
+
:array, :Array
|
197
|
+
end
|
198
|
+
|
199
|
+
# Status
|
200
|
+
attach_function :clear, :upb_Status_Clear, [Status.by_ref], :void
|
201
|
+
attach_function :error_message, :upb_Status_ErrorMessage, [Status.by_ref], :string
|
202
|
+
|
203
|
+
# Generic
|
204
|
+
attach_function :memcmp, [:pointer, :pointer, :size_t], :int
|
205
|
+
attach_function :memcpy, [:pointer, :pointer, :size_t], :int
|
206
|
+
|
207
|
+
# Alternatives to pre-processor macros
|
208
|
+
def self.decode_max_depth(i)
|
209
|
+
i << 16
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,319 @@
|
|
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
|
+
|
8
|
+
module Google
|
9
|
+
module Protobuf
|
10
|
+
class FieldDescriptor
|
11
|
+
attr :field_def, :descriptor_pool
|
12
|
+
|
13
|
+
include Google::Protobuf::Internal::Convert
|
14
|
+
|
15
|
+
# FFI Interface methods and setup
|
16
|
+
extend ::FFI::DataConverter
|
17
|
+
native_type ::FFI::Type::POINTER
|
18
|
+
|
19
|
+
class << self
|
20
|
+
prepend Google::Protobuf::Internal::TypeSafety
|
21
|
+
include Google::Protobuf::Internal::PointerHelper
|
22
|
+
|
23
|
+
# @param value [FieldDescriptor] FieldDescriptor to convert to an FFI native type
|
24
|
+
# @param _ [Object] Unused
|
25
|
+
def to_native(value, _)
|
26
|
+
field_def_ptr = value.instance_variable_get(:@field_def)
|
27
|
+
warn "Underlying field_def was nil!" if field_def_ptr.nil?
|
28
|
+
raise "Underlying field_def was null!" if !field_def_ptr.nil? and field_def_ptr.null?
|
29
|
+
field_def_ptr
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# @param field_def [::FFI::Pointer] FieldDef pointer to be wrapped
|
34
|
+
# @param _ [Object] Unused
|
35
|
+
def from_native(field_def, _ = nil)
|
36
|
+
return nil if field_def.nil? or field_def.null?
|
37
|
+
file_def = Google::Protobuf::FFI.file_def_by_raw_field_def(field_def)
|
38
|
+
descriptor_from_file_def(file_def, field_def)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.new(*arguments, &block)
|
43
|
+
raise "Descriptor objects may not be created from Ruby."
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
inspect
|
48
|
+
end
|
49
|
+
|
50
|
+
def inspect
|
51
|
+
"#{self.class.name}: #{name}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def name
|
55
|
+
@name ||= Google::Protobuf::FFI.get_full_name(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
def json_name
|
59
|
+
@json_name ||= Google::Protobuf::FFI.get_json_name(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
def number
|
63
|
+
@number ||= Google::Protobuf::FFI.get_number(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
def type
|
67
|
+
@type ||= Google::Protobuf::FFI.get_type(self)
|
68
|
+
end
|
69
|
+
|
70
|
+
def label
|
71
|
+
@label ||= Google::Protobuf::FFI::Label[Google::Protobuf::FFI.get_label(self)]
|
72
|
+
end
|
73
|
+
|
74
|
+
def default
|
75
|
+
return nil if Google::Protobuf::FFI.is_sub_message(self)
|
76
|
+
if Google::Protobuf::FFI.is_repeated(self)
|
77
|
+
message_value = Google::Protobuf::FFI::MessageValue.new
|
78
|
+
else
|
79
|
+
message_value = Google::Protobuf::FFI.get_default(self)
|
80
|
+
end
|
81
|
+
enum_def = Google::Protobuf::FFI.get_subtype_as_enum(self)
|
82
|
+
if enum_def.null?
|
83
|
+
convert_upb_to_ruby message_value, c_type
|
84
|
+
else
|
85
|
+
convert_upb_to_ruby message_value, c_type, enum_def
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def submsg_name
|
90
|
+
if defined? @submsg_name
|
91
|
+
@submsg_name
|
92
|
+
else
|
93
|
+
@submsg_name = case c_type
|
94
|
+
when :enum
|
95
|
+
Google::Protobuf::FFI.get_enum_fullname Google::Protobuf::FFI.get_subtype_as_enum self
|
96
|
+
when :message
|
97
|
+
Google::Protobuf::FFI.get_message_fullname Google::Protobuf::FFI.get_subtype_as_message self
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Tests if this field has been set on the argument message.
|
106
|
+
#
|
107
|
+
# @param msg [Google::Protobuf::Message]
|
108
|
+
# @return [Object] Value of the field on this message.
|
109
|
+
# @raise [TypeError] If the field is not defined on this message.
|
110
|
+
def get(msg)
|
111
|
+
if msg.class.descriptor == Google::Protobuf::FFI.get_containing_message_def(self)
|
112
|
+
msg.send :get_field, self
|
113
|
+
else
|
114
|
+
raise TypeError.new "get method called on wrong message type"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def subtype
|
119
|
+
if defined? @subtype
|
120
|
+
@subtype
|
121
|
+
else
|
122
|
+
@subtype = case c_type
|
123
|
+
when :enum
|
124
|
+
Google::Protobuf::FFI.get_subtype_as_enum(self)
|
125
|
+
when :message
|
126
|
+
Google::Protobuf::FFI.get_subtype_as_message(self)
|
127
|
+
else
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Tests if this field has been set on the argument message.
|
135
|
+
#
|
136
|
+
# @param msg [Google::Protobuf::Message]
|
137
|
+
# @return [Boolean] True iff message has this field set
|
138
|
+
# @raise [TypeError] If this field does not exist on the message
|
139
|
+
# @raise [ArgumentError] If this field does not track presence
|
140
|
+
def has?(msg)
|
141
|
+
if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
|
142
|
+
raise TypeError.new "has method called on wrong message type"
|
143
|
+
end
|
144
|
+
unless has_presence?
|
145
|
+
raise ArgumentError.new "does not track presence"
|
146
|
+
end
|
147
|
+
|
148
|
+
Google::Protobuf::FFI.get_message_has msg.instance_variable_get(:@msg), self
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Tests if this field tracks presence.
|
153
|
+
#
|
154
|
+
# @return [Boolean] True iff this field tracks presence
|
155
|
+
def has_presence?
|
156
|
+
@has_presence ||= Google::Protobuf::FFI.get_has_presence(self)
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param msg [Google::Protobuf::Message]
|
160
|
+
def clear(msg)
|
161
|
+
if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
|
162
|
+
raise TypeError.new "clear method called on wrong message type"
|
163
|
+
end
|
164
|
+
Google::Protobuf::FFI.clear_message_field msg.instance_variable_get(:@msg), self
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# call-seq:
|
170
|
+
# FieldDescriptor.set(message, value)
|
171
|
+
#
|
172
|
+
# Sets the value corresponding to this field to the given value on the given
|
173
|
+
# message. Raises an exception if message is of the wrong type. Performs the
|
174
|
+
# ordinary type-checks for field setting.
|
175
|
+
#
|
176
|
+
# @param msg [Google::Protobuf::Message]
|
177
|
+
# @param value [Object]
|
178
|
+
def set(msg, value)
|
179
|
+
if msg.class.descriptor != Google::Protobuf::FFI.get_containing_message_def(self)
|
180
|
+
raise TypeError.new "set method called on wrong message type"
|
181
|
+
end
|
182
|
+
unless set_value_on_message value, msg.instance_variable_get(:@msg), msg.instance_variable_get(:@arena)
|
183
|
+
raise RuntimeError.new "allocation failed"
|
184
|
+
end
|
185
|
+
nil
|
186
|
+
end
|
187
|
+
|
188
|
+
def map?
|
189
|
+
@map ||= Google::Protobuf::FFI.is_map self
|
190
|
+
end
|
191
|
+
|
192
|
+
def repeated?
|
193
|
+
@repeated ||= Google::Protobuf::FFI.is_repeated self
|
194
|
+
end
|
195
|
+
|
196
|
+
def sub_message?
|
197
|
+
@sub_message ||= Google::Protobuf::FFI.is_sub_message self
|
198
|
+
end
|
199
|
+
|
200
|
+
def wrapper?
|
201
|
+
if defined? @wrapper
|
202
|
+
@wrapper
|
203
|
+
else
|
204
|
+
message_descriptor = Google::Protobuf::FFI.get_subtype_as_message(self)
|
205
|
+
@wrapper = message_descriptor.nil? ? false : message_descriptor.send(:wrapper?)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def options
|
210
|
+
@options ||= begin
|
211
|
+
size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
|
212
|
+
temporary_arena = Google::Protobuf::FFI.create_arena
|
213
|
+
buffer = Google::Protobuf::FFI.field_options(self, size_ptr, temporary_arena)
|
214
|
+
Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
|
220
|
+
def initialize(field_def, descriptor_pool)
|
221
|
+
@field_def = field_def
|
222
|
+
@descriptor_pool = descriptor_pool
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.private_constructor(field_def, descriptor_pool)
|
226
|
+
instance = allocate
|
227
|
+
instance.send(:initialize, field_def, descriptor_pool)
|
228
|
+
instance
|
229
|
+
end
|
230
|
+
|
231
|
+
# TODO Can this be added to the public API?
|
232
|
+
def real_containing_oneof
|
233
|
+
@real_containing_oneof ||= Google::Protobuf::FFI.real_containing_oneof self
|
234
|
+
end
|
235
|
+
|
236
|
+
# Implementation details below are subject to breaking changes without
|
237
|
+
# warning and are intended for use only within the gem.
|
238
|
+
|
239
|
+
##
|
240
|
+
# Sets the field this FieldDescriptor represents to the given value on the given message.
|
241
|
+
# @param value [Object] Value to be set
|
242
|
+
# @param msg [::FFI::Pointer] Pointer the the upb_Message
|
243
|
+
# @param arena [Arena] Arena of the message that owns msg
|
244
|
+
def set_value_on_message(value, msg, arena, wrap: false)
|
245
|
+
message_to_alter = msg
|
246
|
+
field_def_to_set = self
|
247
|
+
if map?
|
248
|
+
raise TypeError.new "Expected map" unless value.is_a? Google::Protobuf::Map
|
249
|
+
message_descriptor = subtype
|
250
|
+
|
251
|
+
key_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 1)
|
252
|
+
key_field_type = Google::Protobuf::FFI.get_type(key_field_def)
|
253
|
+
raise TypeError.new "Map key type does not match field's key type" unless key_field_type == value.send(:key_type)
|
254
|
+
|
255
|
+
value_field_def = Google::Protobuf::FFI.get_field_by_number(message_descriptor, 2)
|
256
|
+
value_field_type = Google::Protobuf::FFI.get_type(value_field_def)
|
257
|
+
raise TypeError.new "Map value type does not match field's value type" unless value_field_type == value.send(:value_type)
|
258
|
+
|
259
|
+
raise TypeError.new "Map value type has wrong message/enum class" unless value_field_def.subtype == value.send(:descriptor)
|
260
|
+
|
261
|
+
arena.fuse(value.send(:arena))
|
262
|
+
message_value = Google::Protobuf::FFI::MessageValue.new
|
263
|
+
message_value[:map_val] = value.send(:map_ptr)
|
264
|
+
elsif repeated?
|
265
|
+
raise TypeError.new "Expected repeated field array" unless value.is_a? RepeatedField
|
266
|
+
raise TypeError.new "Repeated field array has wrong message/enum class" unless value.send(:type) == type
|
267
|
+
arena.fuse(value.send(:arena))
|
268
|
+
message_value = Google::Protobuf::FFI::MessageValue.new
|
269
|
+
message_value[:array_val] = value.send(:array)
|
270
|
+
else
|
271
|
+
if value.nil? and (sub_message? or !real_containing_oneof.nil?)
|
272
|
+
Google::Protobuf::FFI.clear_message_field message_to_alter, field_def_to_set
|
273
|
+
return true
|
274
|
+
end
|
275
|
+
if wrap
|
276
|
+
value_field_def = Google::Protobuf::FFI.get_field_by_number subtype, 1
|
277
|
+
type_for_conversion = Google::Protobuf::FFI.get_c_type(value_field_def)
|
278
|
+
raise RuntimeError.new "Not expecting to get a msg or enum when unwrapping" if [:enum, :message].include? type_for_conversion
|
279
|
+
message_value = convert_ruby_to_upb(value, arena, type_for_conversion, nil)
|
280
|
+
message_to_alter = Google::Protobuf::FFI.get_mutable_message(msg, self, arena)[:msg]
|
281
|
+
field_def_to_set = value_field_def
|
282
|
+
else
|
283
|
+
message_value = convert_ruby_to_upb(value, arena, c_type, subtype)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
Google::Protobuf::FFI.set_message_field message_to_alter, field_def_to_set, message_value, arena
|
287
|
+
end
|
288
|
+
|
289
|
+
def c_type
|
290
|
+
@c_type ||= Google::Protobuf::FFI.get_c_type(self)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
class FFI
|
295
|
+
# MessageDef
|
296
|
+
attach_function :get_field_by_index, :upb_MessageDef_Field, [Descriptor, :int], FieldDescriptor
|
297
|
+
attach_function :get_field_by_name, :upb_MessageDef_FindFieldByNameWithSize,[Descriptor, :string, :size_t], FieldDescriptor
|
298
|
+
attach_function :get_field_by_number, :upb_MessageDef_FindFieldByNumber, [Descriptor, :uint32_t], FieldDescriptor
|
299
|
+
|
300
|
+
# FieldDescriptor
|
301
|
+
attach_function :field_options, :FieldDescriptor_serialized_options, [FieldDescriptor, :pointer, Internal::Arena], :pointer
|
302
|
+
attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor
|
303
|
+
attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType
|
304
|
+
attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value
|
305
|
+
attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor
|
306
|
+
attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool
|
307
|
+
attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool
|
308
|
+
attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool
|
309
|
+
attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool
|
310
|
+
attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string
|
311
|
+
attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label
|
312
|
+
attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor
|
313
|
+
attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string
|
314
|
+
attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t
|
315
|
+
attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType
|
316
|
+
attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|