class Protobuf::Field::BaseField

Constants

PACKED_TYPES

Constants

Attributes

message_class[R]

Attributes

name[R]

Attributes

options[R]

Attributes

rule[R]

Attributes

tag[R]

Attributes

type_class[R]

Attributes

Public Class Methods

default() click to toggle source

Class Methods

# File lib/protobuf/field/base_field.rb, line 30
def self.default
  nil
end
new(message_class, rule, type_class, name, tag, options) click to toggle source

Constructor

# File lib/protobuf/field/base_field.rb, line 38
def initialize(message_class, rule, type_class, name, tag, options)
  @message_class = message_class
  @name          = name
  @rule          = rule
  @tag           = tag
  @type_class    = type_class
  @options       = options

  validate_packed_field if packed?
  define_accessor
end

Public Instance Methods

acceptable?(_value) click to toggle source

Public Instance Methods

# File lib/protobuf/field/base_field.rb, line 54
def acceptable?(_value)
  true
end
coerce!(value) click to toggle source
# File lib/protobuf/field/base_field.rb, line 58
def coerce!(value)
  value
end
decode(_bytes) click to toggle source
# File lib/protobuf/field/base_field.rb, line 62
def decode(_bytes)
  fail NotImplementedError, "#{self.class.name}##{__method__}"
end
default() click to toggle source
# File lib/protobuf/field/base_field.rb, line 66
def default
  options[:default]
end
default_value() click to toggle source
# File lib/protobuf/field/base_field.rb, line 70
def default_value
  @default_value ||= case
                     when repeated? then ::Protobuf::Field::FieldArray.new(self).freeze
                     when required? then nil
                     when optional? then typed_default_value
                     end
end
deprecated?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 78
def deprecated?
  options.key?(:deprecated)
end
encode(_value) click to toggle source
# File lib/protobuf/field/base_field.rb, line 82
def encode(_value)
  fail NotImplementedError, "#{self.class.name}##{__method__}"
end
enum?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 90
def enum?
  false
end
extension?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 86
def extension?
  options.key?(:extension)
end
getter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 94
def getter
  name
end
message?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 98
def message?
  false
end
optional?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 102
def optional?
  rule == :optional
end
packed?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 106
def packed?
  repeated? && options.key?(:packed)
end
repeated?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 110
def repeated?
  rule == :repeated
end
repeated_message?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 114
def repeated_message?
  repeated? && message?
end
required?() click to toggle source
# File lib/protobuf/field/base_field.rb, line 118
def required?
  rule == :required
end
set(message_instance, bytes) click to toggle source

FIXME: need to cleanup (rename) this warthog of a method.

# File lib/protobuf/field/base_field.rb, line 123
def set(message_instance, bytes)
  if packed?
    array = message_instance.__send__(getter)
    method = \
      case wire_type
      when ::Protobuf::WireType::FIXED32 then :read_fixed32
      when ::Protobuf::WireType::FIXED64 then :read_fixed64
      when ::Protobuf::WireType::VARINT  then :read_varint
      end
    stream = StringIO.new(bytes)

    until stream.eof?
      array << decode(::Protobuf::Decoder.__send__(method, stream))
    end
  else
    value = decode(bytes)
    if repeated?
      message_instance.__send__(getter) << value
    else
      message_instance.__send__(setter, value)
    end
  end
end
setter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 147
def setter
  @setter ||= "#{name}="
end
to_s() click to toggle source

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

# File lib/protobuf/field/base_field.rb, line 152
def to_s
  "#{rule} #{type_class} #{name} = #{tag} #{default ? "[default=#{default.inspect}]" : ''}"
end
wire_type() click to toggle source
# File lib/protobuf/field/base_field.rb, line 158
def wire_type
  ::Protobuf::WireType::VARINT
end

Private Instance Methods

define_accessor() click to toggle source

Private Instance Methods

# File lib/protobuf/field/base_field.rb, line 168
def define_accessor
  if repeated?
    define_array_getter
    define_array_setter
  else
    define_getter
    define_setter
  end
end
define_array_getter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 178
def define_array_getter
  field = self
  method_name = field.getter

  message_class.class_eval do
    define_method(method_name) do
      @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
    end
  end

  ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
end
define_array_setter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 191
      def define_array_setter
        field = self
        method_name = field.setter

        message_class.class_eval do
          define_method(method_name) do |val|
            if val.is_a?(Array)
              val = val.dup
              val.compact!
            else
              fail TypeError, <<-TYPE_ERROR
                Expected repeated value of type '#{field.type_class}'
                Got '#{val.class}' for repeated protobuf field #{field.name}
              TYPE_ERROR
            end

            if val.nil? || (val.respond_to?(:empty?) && val.empty?)
              @values.delete(field.name)
            else
              @values[field.name] ||= ::Protobuf::Field::FieldArray.new(field)
              @values[field.name].replace(val)
            end
          end
        end

        ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
      end
define_getter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 219
def define_getter
  field = self
  method_name = field.getter

  message_class.class_eval do
    define_method(method_name) do
      @values.fetch(field.name, field.default_value)
    end
  end

  ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
end
define_setter() click to toggle source
# File lib/protobuf/field/base_field.rb, line 232
def define_setter
  field = self
  method_name = field.setter

  message_class.class_eval do
    define_method(method_name) do |val|
      if val.nil? || (val.respond_to?(:empty?) && val.empty?)
        @values.delete(field.name)
      elsif field.acceptable?(val)
        @values[field.name] = field.coerce!(val)
      else
        fail TypeError, "Unacceptable value #{val} for field #{field.name} of type #{field.type_class}"
      end
    end
  end

  ::Protobuf.field_deprecator.deprecate_method(message_class, method_name) if field.deprecated?
end
typed_default_value() click to toggle source
# File lib/protobuf/field/base_field.rb, line 251
def typed_default_value
  if default.nil?
    self.class.default
  else
    default
  end
end
validate_packed_field() click to toggle source
# File lib/protobuf/field/base_field.rb, line 259
def validate_packed_field
  if packed? && ! ::Protobuf::Field::BaseField::PACKED_TYPES.include?(wire_type)
    fail "Can't use packed encoding for '#{type_class}' type"
  end
end