Class: Protobuf::Field::BaseField

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/protobuf/field/base_field.rb

Direct Known Subclasses

BytesField, FloatField, MessageField, VarintField

Constant Summary collapse

OBJECT_MODULE =

Constants

::Protobuf::Field::BaseFieldObjectDefinitions
PACKED_TYPES =
[
  ::Protobuf::WireType::VARINT,
  ::Protobuf::WireType::FIXED32,
  ::Protobuf::WireType::FIXED64,
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

initialize_logger, #log_exception, #log_signature, #logger, #sign_message

Constructor Details

#initialize(message_class, rule, type_class, fully_qualified_name, tag, simple_name, options) ⇒ BaseField

Constructor



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/protobuf/field/base_field.rb', line 39

def initialize(message_class, rule, type_class, fully_qualified_name, tag, simple_name, options)
  @message_class = message_class
  @name = simple_name || fully_qualified_name
  @fully_qualified_name = fully_qualified_name
  @rule          = rule
  @tag           = tag
  @type_class    = type_class
  # Populate the option hash with all the original default field options, for backwards compatibility.
  # However, both default and custom options should ideally be accessed through the Optionable .{get,get!}_option functions.
  @options = options.slice(:ctype, :packed, :deprecated, :lazy, :jstype, :weak, :uninterpreted_option, :default, :extension)
  options.each do |option_name, value|
    set_option(option_name, value)
  end

  @extension = options.key?(:extension)
  @deprecated = options.key?(:deprecated)
  @required = rule == :required
  @repeated = rule == :repeated
  @optional = rule == :optional
  @packed = @repeated && options.key?(:packed)

  validate_packed_field if packed?
  define_accessor(simple_name, fully_qualified_name) if simple_name
  set_repeated_message!
  set_map!
  @value_from_values = nil
  @value_from_values_for_serialization = nil
  @field_predicate = nil
  @field_and_present_predicate = nil
  @set_field = nil
  @set_method = nil
  @to_message_hash = nil
  @to_message_hash_string_keys = nil
  @encode_to_stream = nil

  define_value_from_values!
  define_value_from_values_for_serialization!
  define_field_predicate!
  define_field_and_present_predicate!
  define_set_field!
  define_set_method!
  define_to_message_hash!
  define_encode_to_stream!
  set_default_value!
end

Instance Attribute Details

#default_valueObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def default_value
  @default_value
end

#fully_qualified_nameObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def fully_qualified_name
  @fully_qualified_name
end

#message_classObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def message_class
  @message_class
end

#nameObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def name
  @name
end

#optionsObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def options
  @options
end

#ruleObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def rule
  @rule
end

#tagObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def tag
  @tag
end

#type_classObject (readonly)

Attributes



25
26
27
# File 'lib/protobuf/field/base_field.rb', line 25

def type_class
  @type_class
end

Class Method Details

.defaultObject

Class Methods



31
32
33
# File 'lib/protobuf/field/base_field.rb', line 31

def self.default
  nil
end

Instance Method Details

#acceptable?(_value) ⇒ Boolean

Public Instance Methods

Returns:

  • (Boolean)


89
90
91
# File 'lib/protobuf/field/base_field.rb', line 89

def acceptable?(_value)
  true
end

#coerce!(value) ⇒ Object



93
94
95
# File 'lib/protobuf/field/base_field.rb', line 93

def coerce!(value)
  value
end

#decode(_bytes) ⇒ Object



97
98
99
# File 'lib/protobuf/field/base_field.rb', line 97

def decode(_bytes)
  fail NotImplementedError, "#{self.class.name}##{__method__}"
end

#defaultObject



101
102
103
# File 'lib/protobuf/field/base_field.rb', line 101

def default
  options[:default]
end

#define_encode_to_stream!Object



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/protobuf/field/base_field.rb', line 117

def define_encode_to_stream!
  @encode_to_stream = if repeated? && packed?
                        OBJECT_MODULE::RepeatedPackedEncodeToStream.new(self)
                      elsif repeated?
                        OBJECT_MODULE::RepeatedNotPackedEncodeToStream.new(self)
                      elsif message? || type_class == ::Protobuf::Field::BytesField
                        OBJECT_MODULE::BytesEncodeToStream.new(self)
                      elsif type_class == ::Protobuf::Field::StringField
                        OBJECT_MODULE::StringEncodeToStream.new(self)
                      else
                        OBJECT_MODULE::BaseEncodeToStream.new(self)
                      end
end

#define_field_and_present_predicate!Object



147
148
149
150
151
152
153
# File 'lib/protobuf/field/base_field.rb', line 147

def define_field_and_present_predicate!
  @field_and_present_predicate = if !repeated? && type_class == ::Protobuf::Field::BoolField # boolean present check
                                   OBJECT_MODULE::BoolFieldAndPresentPredicate.new(self)
                                 else
                                   OBJECT_MODULE::BaseFieldAndPresentPredicate.new(self)
                                 end
end

#define_field_predicate!Object



135
136
137
138
139
140
141
# File 'lib/protobuf/field/base_field.rb', line 135

def define_field_predicate!
  @field_predicate = if repeated?
                       OBJECT_MODULE::RepeatedFieldPredicate.new(self)
                     else
                       OBJECT_MODULE::BaseFieldPredicate.new(self)
                     end
end

#define_set_field!Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/protobuf/field/base_field.rb', line 191

def define_set_field!
  @set_field = if map? && required?
                 OBJECT_MODULE::RequiredMapSetField.new(self)
               elsif repeated? && required?
                 OBJECT_MODULE::RequiredRepeatedSetField.new(self)
               elsif type_class == ::Protobuf::Field::StringField && required?
                 OBJECT_MODULE::RequiredStringSetField.new(self)
               elsif required?
                 OBJECT_MODULE::RequiredBaseSetField.new(self)
               elsif map?
                 OBJECT_MODULE::MapSetField.new(self)
               elsif repeated?
                 OBJECT_MODULE::RepeatedSetField.new(self)
               elsif type_class == ::Protobuf::Field::StringField
                 OBJECT_MODULE::StringSetField.new(self)
               else
                 OBJECT_MODULE::BaseSetField.new(self)
               end
end

#define_set_method!Object



286
287
288
289
290
291
292
293
294
295
296
# File 'lib/protobuf/field/base_field.rb', line 286

def define_set_method!
  @set_method = if map?
                  OBJECT_MODULE::MapSetMethod.new(self)
                elsif repeated? && packed?
                  OBJECT_MODULE::RepeatedPackedSetMethod.new(self)
                elsif repeated?
                  OBJECT_MODULE::RepeatedNotPackedSetMethod.new(self)
                else
                  OBJECT_MODULE::BaseSetMethod.new(self)
                end
end

#define_to_message_hash!Object



215
216
217
218
219
220
221
222
223
# File 'lib/protobuf/field/base_field.rb', line 215

def define_to_message_hash!
  if message? || enum? || repeated? || map?
    @to_message_hash = OBJECT_MODULE::ToHashValueToMessageHash.new(self)
    @to_message_hash_string_keys = OBJECT_MODULE::ToHashValueToMessageHashWithStringKey.new(self)
  else
    @to_message_hash = OBJECT_MODULE::BaseToMessageHash.new(self)
    @to_message_hash_string_keys = OBJECT_MODULE::BaseToMessageHashWithStringKey.new(self)
  end
end

#define_value_from_values!Object



159
160
161
162
163
164
165
166
167
168
169
# File 'lib/protobuf/field/base_field.rb', line 159

def define_value_from_values!
  @value_from_values = if map?
                         OBJECT_MODULE::MapValueFromValues.new(self)
                       elsif repeated?
                         OBJECT_MODULE::RepeatedFieldValueFromValues.new(self)
                       elsif type_class == ::Protobuf::Field::BoolField # boolean present check
                         OBJECT_MODULE::BoolFieldValueFromValues.new(self)
                       else
                         OBJECT_MODULE::BaseFieldValueFromValues.new(self)
                       end
end

#define_value_from_values_for_serialization!Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/protobuf/field/base_field.rb', line 175

def define_value_from_values_for_serialization!
  @value_from_values_for_serialization = if map?
                                           OBJECT_MODULE::MapValueFromValuesForSerialization.new(self)
                                         elsif repeated?
                                           OBJECT_MODULE::RepeatedFieldValueFromValuesForSerialization.new(self)
                                         elsif type_class == ::Protobuf::Field::BoolField # boolean present check
                                           OBJECT_MODULE::BoolFieldValueFromValuesForSerialization.new(self)
                                         else
                                           OBJECT_MODULE::BaseFieldValueFromValuesForSerialization.new(self)
                                         end
end

#deprecated?Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/protobuf/field/base_field.rb', line 233

def deprecated?
  @deprecated
end

#encode(_value) ⇒ Object



237
238
239
# File 'lib/protobuf/field/base_field.rb', line 237

def encode(_value)
  fail NotImplementedError, "#{self.class.name}##{__method__}"
end

#encode_to_stream(value, stream) ⇒ Object



131
132
133
# File 'lib/protobuf/field/base_field.rb', line 131

def encode_to_stream(value, stream)
  @encode_to_stream.call(value, stream)
end

#enum?Boolean

Returns:

  • (Boolean)


245
246
247
# File 'lib/protobuf/field/base_field.rb', line 245

def enum?
  false
end

#extension?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/protobuf/field/base_field.rb', line 241

def extension?
  @extension
end

#field?(values) ⇒ Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/protobuf/field/base_field.rb', line 143

def field?(values)
  @field_predicate.call(values)
end

#field_and_present?(values) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/protobuf/field/base_field.rb', line 155

def field_and_present?(values)
  @field_and_present_predicate.call(values)
end

#fully_qualified_name_only!Object



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/protobuf/field/base_field.rb', line 324

def fully_qualified_name_only!
  @name = @fully_qualified_name

  ##
  # Recreate all of the meta methods as they may have used the original `name` value
  #
  define_value_from_values!
  define_value_from_values_for_serialization!
  define_field_predicate!
  define_field_and_present_predicate!
  define_set_field!
  define_set_method!
  define_to_message_hash!
  define_encode_to_stream!
end

#map?Boolean

Returns:

  • (Boolean)


258
259
260
# File 'lib/protobuf/field/base_field.rb', line 258

def map?
  @is_map
end

#message?Boolean

Returns:

  • (Boolean)


249
250
251
# File 'lib/protobuf/field/base_field.rb', line 249

def message?
  false
end

#optional?Boolean

Returns:

  • (Boolean)


262
263
264
# File 'lib/protobuf/field/base_field.rb', line 262

def optional?
  @optional
end

#packed?Boolean

Returns:

  • (Boolean)


266
267
268
# File 'lib/protobuf/field/base_field.rb', line 266

def packed?
  @packed
end

#repeated?Boolean

Returns:

  • (Boolean)


270
271
272
# File 'lib/protobuf/field/base_field.rb', line 270

def repeated?
  @repeated
end

#repeated_message?Boolean

Returns:

  • (Boolean)


278
279
280
# File 'lib/protobuf/field/base_field.rb', line 278

def repeated_message?
  @repeated_message
end

#required?Boolean

Returns:

  • (Boolean)


282
283
284
# File 'lib/protobuf/field/base_field.rb', line 282

def required?
  @required
end

#set(message_instance, bytes) ⇒ Object



298
299
300
# File 'lib/protobuf/field/base_field.rb', line 298

def set(message_instance, bytes)
  @set_method.call(message_instance, bytes)
end

#set_default_value!Object



105
106
107
108
109
110
111
112
113
114
115
# File 'lib/protobuf/field/base_field.rb', line 105

def set_default_value!
  @default_value ||= if optional? || required?
                       typed_default_value
                     elsif map?
                       ::Protobuf::Field::FieldHash.new(self).freeze
                     elsif repeated?
                       ::Protobuf::Field::FieldArray.new(self).freeze
                     else
                       fail "Unknown field label -- something went very wrong"
                     end
end

#set_field(values, value, ignore_nil_for_repeated, message_instance) ⇒ Object



211
212
213
# File 'lib/protobuf/field/base_field.rb', line 211

def set_field(values, value, ignore_nil_for_repeated, message_instance)
  @set_field.call(values, value, ignore_nil_for_repeated, message_instance)
end

#set_map!Object



253
254
255
256
# File 'lib/protobuf/field/base_field.rb', line 253

def set_map!
  set_repeated_message!
  @is_map = repeated_message? && type_class.get_option!(:map_entry)
end

#set_repeated_message!Object



274
275
276
# File 'lib/protobuf/field/base_field.rb', line 274

def set_repeated_message!
  @repeated_message = repeated? && message?
end

#tag_encodedObject



302
303
304
305
306
307
308
309
310
311
# File 'lib/protobuf/field/base_field.rb', line 302

def tag_encoded
  @tag_encoded ||= begin
                     case
                     when repeated? && packed?
                       ::Protobuf::Field::VarintField.encode((tag << 3) | ::Protobuf::WireType::LENGTH_DELIMITED)
                     else
                       ::Protobuf::Field::VarintField.encode((tag << 3) | wire_type)
                     end
                   end
end

#to_message_hash(values, result) ⇒ Object



225
226
227
# File 'lib/protobuf/field/base_field.rb', line 225

def to_message_hash(values, result)
  @to_message_hash.call(values, result)
end

#to_message_hash_with_string_key(values, result) ⇒ Object



229
230
231
# File 'lib/protobuf/field/base_field.rb', line 229

def to_message_hash_with_string_key(values, result)
  @to_message_hash_string_keys.call(values, result)
end

#to_sObject

FIXME: add packed, deprecated, extension options to to_s output



314
315
316
# File 'lib/protobuf/field/base_field.rb', line 314

def to_s
  "#{rule} #{type_class} #{name} = #{tag} #{default ? "[default=#{default.inspect}]" : ''}"
end

#value_from_values(values) ⇒ Object



171
172
173
# File 'lib/protobuf/field/base_field.rb', line 171

def value_from_values(values)
  @value_from_values.call(values)
end

#value_from_values_for_serialization(values) ⇒ Object



187
188
189
# File 'lib/protobuf/field/base_field.rb', line 187

def value_from_values_for_serialization(values)
  @value_from_values_for_serialization.call(values)
end

#wire_typeObject



320
321
322
# File 'lib/protobuf/field/base_field.rb', line 320

def wire_type
  ::Protobuf::WireType::VARINT
end