Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

173 lines
5.6 KiB

# Protocol Buffers - Google's data interchange format
# Copyright 2022 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
module Google
module Protobuf
class EnumDescriptor
attr :descriptor_pool, :enum_def
include Enumerable
# FFI Interface methods and setup
extend ::FFI::DataConverter
native_type ::FFI::Type::POINTER
class << self
prepend Google::Protobuf::Internal::TypeSafety
include Google::Protobuf::Internal::PointerHelper
# @param value [EnumDescriptor] EnumDescriptor to convert to an FFI native type
# @param _ [Object] Unused
def to_native(value, _)
value.instance_variable_get(:@enum_def) || ::FFI::Pointer::NULL
end
##
# @param enum_def [::FFI::Pointer] EnumDef pointer to be wrapped
# @param _ [Object] Unused
def from_native(enum_def, _)
return nil if enum_def.nil? or enum_def.null?
file_def = Google::Protobuf::FFI.get_message_file_def enum_def
descriptor_from_file_def(file_def, enum_def)
end
end
def self.new(*arguments, &block)
raise "Descriptor objects may not be created from Ruby."
end
def file_descriptor
@descriptor_pool.send(:get_file_descriptor, Google::Protobuf::FFI.get_enum_file_descriptor(self))
end
def name
Google::Protobuf::FFI.get_enum_fullname(self)
end
def to_s
inspect
end
def inspect
"#{self.class.name}: #{name}"
end
def lookup_name(name)
self.class.send(:lookup_name, self, name)
end
def lookup_value(number)
self.class.send(:lookup_value, self, number)
end
def each &block
n = Google::Protobuf::FFI.enum_value_count(self)
0.upto(n - 1) do |i|
enum_value = Google::Protobuf::FFI.enum_value_by_index(self, i)
yield(Google::Protobuf::FFI.enum_name(enum_value).to_sym, Google::Protobuf::FFI.enum_number(enum_value))
end
nil
end
def enummodule
if @module.nil?
@module = build_enum_module
end
@module
end
def options
@options ||= begin
size_ptr = ::FFI::MemoryPointer.new(:size_t, 1)
temporary_arena = Google::Protobuf::FFI.create_arena
buffer = Google::Protobuf::FFI.enum_options(self, size_ptr, temporary_arena)
opts = Google::Protobuf::EnumOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze)
opts.clear_features()
opts.freeze
end
end
private
def initialize(enum_def, descriptor_pool)
@descriptor_pool = descriptor_pool
@enum_def = enum_def
@module = nil
end
def self.private_constructor(enum_def, descriptor_pool)
instance = allocate
instance.send(:initialize, enum_def, descriptor_pool)
instance
end
def self.lookup_value(enum_def, number)
enum_value = Google::Protobuf::FFI.enum_value_by_number(enum_def, number)
if enum_value.null?
nil
else
Google::Protobuf::FFI.enum_name(enum_value).to_sym
end
end
def self.lookup_name(enum_def, name)
enum_value = Google::Protobuf::FFI.enum_value_by_name(enum_def, name.to_s, name.size)
if enum_value.null?
nil
else
Google::Protobuf::FFI.enum_number(enum_value)
end
end
def build_enum_module
descriptor = self
dynamic_module = Module.new do
@descriptor = descriptor
class << self
attr_accessor :descriptor
end
def self.lookup(number)
descriptor.lookup_value number
end
def self.resolve(name)
descriptor.lookup_name name
end
end
self.each do |name, value|
if name[0] < 'A' || name[0] > 'Z'
if name[0] >= 'a' and name[0] <= 'z'
name = name[0].upcase + name[1..-1] # auto capitalize
else
warn(
"Enum value '#{name}' does not start with an uppercase letter " +
"as is required for Ruby constants.")
next
end
end
dynamic_module.const_set(name.to_sym, value)
end
dynamic_module
end
end
class FFI
# EnumDescriptor
attach_function :get_enum_file_descriptor, :upb_EnumDef_File, [EnumDescriptor], :FileDef
attach_function :enum_value_by_name, :upb_EnumDef_FindValueByNameWithSize,[EnumDescriptor, :string, :size_t], :EnumValueDef
attach_function :enum_value_by_number, :upb_EnumDef_FindValueByNumber, [EnumDescriptor, :int], :EnumValueDef
attach_function :get_enum_fullname, :upb_EnumDef_FullName, [EnumDescriptor], :string
attach_function :enum_options, :EnumDescriptor_serialized_options, [EnumDescriptor, :pointer, Internal::Arena], :pointer
attach_function :enum_value_by_index, :upb_EnumDef_Value, [EnumDescriptor, :int], :EnumValueDef
attach_function :enum_value_count, :upb_EnumDef_ValueCount, [EnumDescriptor], :int
attach_function :enum_name, :upb_EnumValueDef_Name, [:EnumValueDef], :string
attach_function :enum_number, :upb_EnumValueDef_Number, [:EnumValueDef], :int
end
end
end