Add dependencies locally
This commit is contained in:
79
deps/protobuf/ruby/lib/google/protobuf.rb
vendored
Normal file
79
deps/protobuf/ruby/lib/google/protobuf.rb
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
# https://developers.google.com/protocol-buffers/
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# require mixins before we hook them into the java & c code
|
||||
require 'google/protobuf/message_exts'
|
||||
|
||||
# We define these before requiring the platform-specific modules.
|
||||
# That way the module init can grab references to these.
|
||||
module Google
|
||||
module Protobuf
|
||||
class Error < StandardError; end
|
||||
class ParseError < Error; end
|
||||
class TypeError < ::TypeError; end
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_PLATFORM == "java"
|
||||
require 'json'
|
||||
require 'google/protobuf_java'
|
||||
else
|
||||
begin
|
||||
require "google/#{RUBY_VERSION.sub(/\.\d+$/, '')}/protobuf_c"
|
||||
rescue LoadError
|
||||
require 'google/protobuf_c'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
require 'google/protobuf/descriptor_dsl'
|
||||
require 'google/protobuf/repeated_field'
|
||||
|
||||
module Google
|
||||
module Protobuf
|
||||
|
||||
def self.encode(msg, options = {})
|
||||
msg.to_proto(options)
|
||||
end
|
||||
|
||||
def self.encode_json(msg, options = {})
|
||||
msg.to_json(options)
|
||||
end
|
||||
|
||||
def self.decode(klass, proto, options = {})
|
||||
klass.decode(proto, options)
|
||||
end
|
||||
|
||||
def self.decode_json(klass, json, options = {})
|
||||
klass.decode_json(json, options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
465
deps/protobuf/ruby/lib/google/protobuf/descriptor_dsl.rb
vendored
Normal file
465
deps/protobuf/ruby/lib/google/protobuf/descriptor_dsl.rb
vendored
Normal file
@ -0,0 +1,465 @@
|
||||
#!/usr/bin/ruby
|
||||
#
|
||||
# Code that implements the DSL for defining proto messages.
|
||||
|
||||
# Suppress warning: loading in progress, circular require considered harmful.
|
||||
# This circular require is intentional to avoid missing dependency.
|
||||
begin
|
||||
old_verbose, $VERBOSE = $VERBOSE, nil
|
||||
require 'google/protobuf/descriptor_pb'
|
||||
ensure
|
||||
$VERBOSE = old_verbose
|
||||
end
|
||||
|
||||
module Google
|
||||
module Protobuf
|
||||
module Internal
|
||||
class AtomicCounter
|
||||
def initialize
|
||||
@n = 0
|
||||
@mu = Mutex.new
|
||||
end
|
||||
|
||||
def get_and_increment
|
||||
n = @n
|
||||
@mu.synchronize {
|
||||
@n += 1
|
||||
}
|
||||
return n
|
||||
end
|
||||
end
|
||||
|
||||
class Builder
|
||||
@@file_number = AtomicCounter.new
|
||||
|
||||
def initialize(pool)
|
||||
@pool = pool
|
||||
@default_file = nil # Constructed lazily
|
||||
end
|
||||
|
||||
def add_file(name, options={}, &block)
|
||||
builder = FileBuilder.new(@pool, name, options)
|
||||
builder.instance_eval(&block)
|
||||
internal_add_file(builder)
|
||||
end
|
||||
|
||||
def add_message(name, &block)
|
||||
internal_default_file.add_message(name, &block)
|
||||
end
|
||||
|
||||
def add_enum(name, &block)
|
||||
internal_default_file.add_enum(name, &block)
|
||||
end
|
||||
|
||||
# ---- Internal methods, not part of the DSL ----
|
||||
|
||||
def build
|
||||
if @default_file
|
||||
internal_add_file(@default_file)
|
||||
end
|
||||
end
|
||||
|
||||
private def internal_add_file(file_builder)
|
||||
proto = file_builder.build
|
||||
serialized = Google::Protobuf::FileDescriptorProto.encode(proto)
|
||||
@pool.add_serialized_file(serialized)
|
||||
end
|
||||
|
||||
private def internal_default_file
|
||||
number = @@file_number.get_and_increment
|
||||
filename = "ruby_default_file#{number}.proto"
|
||||
@default_file ||= FileBuilder.new(@pool, filename)
|
||||
end
|
||||
end
|
||||
|
||||
class FileBuilder
|
||||
def initialize(pool, name, options={})
|
||||
@pool = pool
|
||||
@file_proto = Google::Protobuf::FileDescriptorProto.new(
|
||||
name: name,
|
||||
syntax: options.fetch(:syntax, "proto3")
|
||||
)
|
||||
end
|
||||
|
||||
def add_message(name, &block)
|
||||
builder = MessageBuilder.new(name, self, @file_proto)
|
||||
builder.instance_eval(&block)
|
||||
builder.internal_add_synthetic_oneofs
|
||||
end
|
||||
|
||||
def add_enum(name, &block)
|
||||
EnumBuilder.new(name, @file_proto).instance_eval(&block)
|
||||
end
|
||||
|
||||
# ---- Internal methods, not part of the DSL ----
|
||||
|
||||
# These methods fix up the file descriptor to account for differences
|
||||
# between the DSL and FileDescriptorProto.
|
||||
|
||||
# The DSL can omit a package name; here we infer what the package is if
|
||||
# was not specified.
|
||||
def infer_package(names)
|
||||
# Package is longest common prefix ending in '.', if any.
|
||||
if not names.empty?
|
||||
min, max = names.minmax
|
||||
last_common_dot = nil
|
||||
min.size.times { |i|
|
||||
if min[i] != max[i] then break end
|
||||
if min[i] == "." then last_common_dot = i end
|
||||
}
|
||||
if last_common_dot
|
||||
return min.slice(0, last_common_dot)
|
||||
end
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def rewrite_enum_default(field)
|
||||
if field.type != :TYPE_ENUM or !field.has_default_value? or !field.has_type_name?
|
||||
return
|
||||
end
|
||||
|
||||
value = field.default_value
|
||||
type_name = field.type_name
|
||||
|
||||
if value.empty? or value[0].ord < "0".ord or value[0].ord > "9".ord
|
||||
return
|
||||
end
|
||||
|
||||
if type_name.empty? || type_name[0] != "."
|
||||
return
|
||||
end
|
||||
|
||||
type_name = type_name[1..-1]
|
||||
as_int = Integer(value) rescue return
|
||||
|
||||
enum_desc = @pool.lookup(type_name)
|
||||
if enum_desc.is_a?(Google::Protobuf::EnumDescriptor)
|
||||
# Enum was defined in a previous file.
|
||||
name = enum_desc.lookup_value(as_int)
|
||||
if name
|
||||
# Update the default value in the proto.
|
||||
field.default_value = name
|
||||
end
|
||||
else
|
||||
# See if enum was defined in this file.
|
||||
@file_proto.enum_type.each { |enum_proto|
|
||||
if enum_proto.name == type_name
|
||||
enum_proto.value.each { |enum_value_proto|
|
||||
if enum_value_proto.number == as_int
|
||||
# Update the default value in the proto.
|
||||
field.default_value = enum_value_proto.name
|
||||
return
|
||||
end
|
||||
}
|
||||
# We found the right enum, but no value matched.
|
||||
return
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Historically we allowed enum defaults to be specified as a number.
|
||||
# In retrospect this was a mistake as descriptors require defaults to
|
||||
# be specified as a label. This can make a difference if multiple
|
||||
# labels have the same number.
|
||||
#
|
||||
# Here we do a pass over all enum defaults and rewrite numeric defaults
|
||||
# by looking up their labels. This is complicated by the fact that the
|
||||
# enum definition can live in either the symtab or the file_proto.
|
||||
#
|
||||
# We take advantage of the fact that this is called *before* enums or
|
||||
# messages are nested in other messages, so we only have to iterate
|
||||
# one level deep.
|
||||
def rewrite_enum_defaults
|
||||
@file_proto.message_type.each { |msg|
|
||||
msg.field.each { |field|
|
||||
rewrite_enum_default(field)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# We have to do some relatively complicated logic here for backward
|
||||
# compatibility.
|
||||
#
|
||||
# In descriptor.proto, messages are nested inside other messages if that is
|
||||
# what the original .proto file looks like. For example, suppose we have this
|
||||
# foo.proto:
|
||||
#
|
||||
# package foo;
|
||||
# message Bar {
|
||||
# message Baz {}
|
||||
# }
|
||||
#
|
||||
# The descriptor for this must look like this:
|
||||
#
|
||||
# file {
|
||||
# name: "test.proto"
|
||||
# package: "foo"
|
||||
# message_type {
|
||||
# name: "Bar"
|
||||
# nested_type {
|
||||
# name: "Baz"
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# However, the Ruby generated code has always generated messages in a flat,
|
||||
# non-nested way:
|
||||
#
|
||||
# Google::Protobuf::DescriptorPool.generated_pool.build do
|
||||
# add_message "foo.Bar" do
|
||||
# end
|
||||
# add_message "foo.Bar.Baz" do
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Here we need to do a translation where we turn this generated code into the
|
||||
# above descriptor. We need to infer that "foo" is the package name, and not
|
||||
# a message itself. */
|
||||
|
||||
def split_parent_name(msg_or_enum)
|
||||
name = msg_or_enum.name
|
||||
idx = name.rindex(?.)
|
||||
if idx
|
||||
return name[0...idx], name[idx+1..-1]
|
||||
else
|
||||
return nil, name
|
||||
end
|
||||
end
|
||||
|
||||
def get_parent_msg(msgs_by_name, name, parent_name)
|
||||
parent_msg = msgs_by_name[parent_name]
|
||||
if parent_msg.nil?
|
||||
raise "To define name #{name}, there must be a message named #{parent_name} to enclose it"
|
||||
end
|
||||
return parent_msg
|
||||
end
|
||||
|
||||
def fix_nesting
|
||||
# Calculate and update package.
|
||||
msgs_by_name = @file_proto.message_type.map { |msg| [msg.name, msg] }.to_h
|
||||
enum_names = @file_proto.enum_type.map { |enum_proto| enum_proto.name }
|
||||
|
||||
package = infer_package(msgs_by_name.keys + enum_names)
|
||||
if package
|
||||
@file_proto.package = package
|
||||
end
|
||||
|
||||
# Update nesting based on package.
|
||||
final_msgs = Google::Protobuf::RepeatedField.new(:message, Google::Protobuf::DescriptorProto)
|
||||
final_enums = Google::Protobuf::RepeatedField.new(:message, Google::Protobuf::EnumDescriptorProto)
|
||||
|
||||
# Note: We don't iterate over msgs_by_name.values because we want to
|
||||
# preserve order as listed in the DSL.
|
||||
@file_proto.message_type.each { |msg|
|
||||
parent_name, msg.name = split_parent_name(msg)
|
||||
if parent_name == package
|
||||
final_msgs << msg
|
||||
else
|
||||
get_parent_msg(msgs_by_name, msg.name, parent_name).nested_type << msg
|
||||
end
|
||||
}
|
||||
|
||||
@file_proto.enum_type.each { |enum|
|
||||
parent_name, enum.name = split_parent_name(enum)
|
||||
if parent_name == package
|
||||
final_enums << enum
|
||||
else
|
||||
get_parent_msg(msgs_by_name, enum.name, parent_name).enum_type << enum
|
||||
end
|
||||
}
|
||||
|
||||
@file_proto.message_type = final_msgs
|
||||
@file_proto.enum_type = final_enums
|
||||
end
|
||||
|
||||
def internal_file_proto
|
||||
@file_proto
|
||||
end
|
||||
|
||||
def build
|
||||
rewrite_enum_defaults
|
||||
fix_nesting
|
||||
return @file_proto
|
||||
end
|
||||
end
|
||||
|
||||
class MessageBuilder
|
||||
def initialize(name, file_builder, file_proto)
|
||||
@file_builder = file_builder
|
||||
@msg_proto = Google::Protobuf::DescriptorProto.new(
|
||||
:name => name
|
||||
)
|
||||
file_proto.message_type << @msg_proto
|
||||
end
|
||||
|
||||
def optional(name, type, number, type_class=nil, options=nil)
|
||||
internal_add_field(:LABEL_OPTIONAL, name, type, number, type_class, options)
|
||||
end
|
||||
|
||||
def proto3_optional(name, type, number, type_class=nil, options=nil)
|
||||
internal_add_field(:LABEL_OPTIONAL, name, type, number, type_class, options,
|
||||
proto3_optional: true)
|
||||
end
|
||||
|
||||
def required(name, type, number, type_class=nil, options=nil)
|
||||
internal_add_field(:LABEL_REQUIRED, name, type, number, type_class, options)
|
||||
end
|
||||
|
||||
def repeated(name, type, number, type_class = nil, options=nil)
|
||||
internal_add_field(:LABEL_REPEATED, name, type, number, type_class, options)
|
||||
end
|
||||
|
||||
def oneof(name, &block)
|
||||
OneofBuilder.new(name, self).instance_eval(&block)
|
||||
end
|
||||
|
||||
# Defines a new map field on this message type with the given key and
|
||||
# value types, tag number, and type class (for message and enum value
|
||||
# types). The key type must be :int32/:uint32/:int64/:uint64, :bool, or
|
||||
# :string. The value type type must be a Ruby symbol (as accepted by
|
||||
# FieldDescriptor#type=) and the type_class must be a string, if
|
||||
# present (as accepted by FieldDescriptor#submsg_name=).
|
||||
def map(name, key_type, value_type, number, value_type_class = nil)
|
||||
if key_type == :float or key_type == :double or key_type == :enum or
|
||||
key_type == :message
|
||||
raise ArgError, "Not an acceptable key type: " + key_type
|
||||
end
|
||||
entry_name = "#{@msg_proto.name}_MapEntry_#{name}"
|
||||
|
||||
@file_builder.add_message entry_name do
|
||||
optional :key, key_type, 1
|
||||
optional :value, value_type, 2, value_type_class
|
||||
end
|
||||
options = @file_builder.internal_file_proto.message_type.last.options ||= MessageOptions.new
|
||||
options.map_entry = true
|
||||
repeated name, :message, number, entry_name
|
||||
end
|
||||
|
||||
# ---- Internal methods, not part of the DSL ----
|
||||
|
||||
def internal_add_synthetic_oneofs
|
||||
# We have to build a set of all names, to ensure that synthetic oneofs
|
||||
# are not creating conflicts
|
||||
names = {}
|
||||
@msg_proto.field.each { |field| names[field.name] = true }
|
||||
@msg_proto.oneof_decl.each { |oneof| names[oneof.name] = true }
|
||||
|
||||
@msg_proto.field.each { |field|
|
||||
if field.proto3_optional
|
||||
# Prepend '_' until we are no longer conflicting.
|
||||
oneof_name = field.name
|
||||
while names[oneof_name]
|
||||
oneof_name = "_" + oneof_name
|
||||
end
|
||||
names[oneof_name] = true
|
||||
field.oneof_index = @msg_proto.oneof_decl.size
|
||||
@msg_proto.oneof_decl << Google::Protobuf::OneofDescriptorProto.new(
|
||||
name: oneof_name
|
||||
)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def internal_add_field(label, name, type, number, type_class, options,
|
||||
oneof_index: nil, proto3_optional: false)
|
||||
# Allow passing either:
|
||||
# - (name, type, number, options) or
|
||||
# - (name, type, number, type_class, options)
|
||||
if options.nil? and type_class.instance_of?(Hash)
|
||||
options = type_class;
|
||||
type_class = nil;
|
||||
end
|
||||
|
||||
field_proto = Google::Protobuf::FieldDescriptorProto.new(
|
||||
:label => label,
|
||||
:name => name,
|
||||
:type => ("TYPE_" + type.to_s.upcase).to_sym,
|
||||
:number => number
|
||||
)
|
||||
|
||||
if type_class
|
||||
# Make it an absolute type name by prepending a dot.
|
||||
field_proto.type_name = "." + type_class
|
||||
end
|
||||
|
||||
if oneof_index
|
||||
field_proto.oneof_index = oneof_index
|
||||
end
|
||||
|
||||
if proto3_optional
|
||||
field_proto.proto3_optional = true
|
||||
end
|
||||
|
||||
if options
|
||||
if options.key?(:default)
|
||||
default = options[:default]
|
||||
if !default.instance_of?(String)
|
||||
# Call #to_s since all defaults are strings in the descriptor.
|
||||
default = default.to_s
|
||||
end
|
||||
# XXX: we should be C-escaping bytes defaults.
|
||||
field_proto.default_value = default.dup.force_encoding("UTF-8")
|
||||
end
|
||||
if options.key?(:json_name)
|
||||
field_proto.json_name = options[:json_name]
|
||||
end
|
||||
end
|
||||
|
||||
@msg_proto.field << field_proto
|
||||
end
|
||||
|
||||
def internal_msg_proto
|
||||
@msg_proto
|
||||
end
|
||||
end
|
||||
|
||||
class OneofBuilder
|
||||
def initialize(name, msg_builder)
|
||||
@msg_builder = msg_builder
|
||||
oneof_proto = Google::Protobuf::OneofDescriptorProto.new(
|
||||
:name => name
|
||||
)
|
||||
msg_proto = msg_builder.internal_msg_proto
|
||||
@oneof_index = msg_proto.oneof_decl.size
|
||||
msg_proto.oneof_decl << oneof_proto
|
||||
end
|
||||
|
||||
def optional(name, type, number, type_class=nil, options=nil)
|
||||
@msg_builder.internal_add_field(
|
||||
:LABEL_OPTIONAL, name, type, number, type_class, options,
|
||||
oneof_index: @oneof_index)
|
||||
end
|
||||
end
|
||||
|
||||
class EnumBuilder
|
||||
def initialize(name, file_proto)
|
||||
@enum_proto = Google::Protobuf::EnumDescriptorProto.new(
|
||||
:name => name
|
||||
)
|
||||
file_proto.enum_type << @enum_proto
|
||||
end
|
||||
|
||||
def value(name, number)
|
||||
enum_value_proto = Google::Protobuf::EnumValueDescriptorProto.new(
|
||||
name: name,
|
||||
number: number
|
||||
)
|
||||
@enum_proto.value << enum_value_proto
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Re-open the class (the rest of the class is implemented in C)
|
||||
class DescriptorPool
|
||||
def build(&block)
|
||||
builder = Internal::Builder.new(self)
|
||||
builder.instance_eval(&block)
|
||||
builder.build
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
53
deps/protobuf/ruby/lib/google/protobuf/message_exts.rb
vendored
Normal file
53
deps/protobuf/ruby/lib/google/protobuf/message_exts.rb
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
# https://developers.google.com/protocol-buffers/
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Google
|
||||
module Protobuf
|
||||
module MessageExts
|
||||
|
||||
#this is only called in jruby; mri loades the ClassMethods differently
|
||||
def self.included(klass)
|
||||
klass.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
end
|
||||
|
||||
def to_json(options = {})
|
||||
self.class.encode_json(self, options)
|
||||
end
|
||||
|
||||
def to_proto(options = {})
|
||||
self.class.encode(self, options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
188
deps/protobuf/ruby/lib/google/protobuf/repeated_field.rb
vendored
Normal file
188
deps/protobuf/ruby/lib/google/protobuf/repeated_field.rb
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
# https://developers.google.com/protocol-buffers/
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'forwardable'
|
||||
|
||||
#
|
||||
# This class makes RepeatedField act (almost-) like a Ruby Array.
|
||||
# It has convenience methods that extend the core C or Java based
|
||||
# methods.
|
||||
#
|
||||
# This is a best-effort to mirror Array behavior. Two comments:
|
||||
# 1) patches always welcome :)
|
||||
# 2) if performance is an issue, feel free to rewrite the method
|
||||
# in jruby and C. The source code has plenty of examples
|
||||
#
|
||||
# KNOWN ISSUES
|
||||
# - #[]= doesn't allow less used approaches such as `arr[1, 2] = 'fizz'`
|
||||
# - #concat should return the orig array
|
||||
# - #push should accept multiple arguments and push them all at the same time
|
||||
#
|
||||
module Google
|
||||
module Protobuf
|
||||
class RepeatedField
|
||||
extend Forwardable
|
||||
|
||||
# methods defined in C or Java:
|
||||
# +
|
||||
# [], at
|
||||
# []=
|
||||
# concat
|
||||
# clear
|
||||
# dup, clone
|
||||
# each
|
||||
# push, <<
|
||||
# replace
|
||||
# length, size
|
||||
# ==
|
||||
# to_ary, to_a
|
||||
# also all enumerable
|
||||
#
|
||||
# NOTE: using delegators rather than method_missing to make the
|
||||
# relationship explicit instead of implicit
|
||||
def_delegators :to_ary,
|
||||
:&, :*, :-, :'<=>',
|
||||
:assoc, :bsearch, :bsearch_index, :combination, :compact, :count,
|
||||
:cycle, :dig, :drop, :drop_while, :eql?, :fetch, :find_index, :flatten,
|
||||
:include?, :index, :inspect, :join,
|
||||
:pack, :permutation, :product, :pretty_print, :pretty_print_cycle,
|
||||
:rassoc, :repeated_combination, :repeated_permutation, :reverse,
|
||||
:rindex, :rotate, :sample, :shuffle, :shelljoin,
|
||||
:to_s, :transpose, :uniq, :|
|
||||
|
||||
|
||||
def first(n=nil)
|
||||
n ? self[0...n] : self[0]
|
||||
end
|
||||
|
||||
|
||||
def last(n=nil)
|
||||
n ? self[(self.size-n-1)..-1] : self[-1]
|
||||
end
|
||||
|
||||
|
||||
def pop(n=nil)
|
||||
if n
|
||||
results = []
|
||||
n.times{ results << pop_one }
|
||||
return results
|
||||
else
|
||||
return pop_one
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def empty?
|
||||
self.size == 0
|
||||
end
|
||||
|
||||
# array aliases into enumerable
|
||||
alias_method :each_index, :each_with_index
|
||||
alias_method :slice, :[]
|
||||
alias_method :values_at, :select
|
||||
alias_method :map, :collect
|
||||
|
||||
|
||||
class << self
|
||||
def define_array_wrapper_method(method_name)
|
||||
define_method(method_name) do |*args, &block|
|
||||
arr = self.to_a
|
||||
result = arr.send(method_name, *args)
|
||||
self.replace(arr)
|
||||
return result if result
|
||||
return block ? block.call : result
|
||||
end
|
||||
end
|
||||
private :define_array_wrapper_method
|
||||
|
||||
|
||||
def define_array_wrapper_with_result_method(method_name)
|
||||
define_method(method_name) do |*args, &block|
|
||||
# result can be an Enumerator, Array, or nil
|
||||
# Enumerator can sometimes be returned if a block is an optional argument and it is not passed in
|
||||
# nil usually specifies that no change was made
|
||||
result = self.to_a.send(method_name, *args, &block)
|
||||
if result
|
||||
new_arr = result.to_a
|
||||
self.replace(new_arr)
|
||||
if result.is_a?(Enumerator)
|
||||
# generate a fresh enum; rewinding the exiting one, in Ruby 2.2, will
|
||||
# reset the enum with the same length, but all the #next calls will
|
||||
# return nil
|
||||
result = new_arr.to_enum
|
||||
# generate a wrapper enum so any changes which occur by a chained
|
||||
# enum can be captured
|
||||
ie = ProxyingEnumerator.new(self, result)
|
||||
result = ie.to_enum
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
private :define_array_wrapper_with_result_method
|
||||
end
|
||||
|
||||
|
||||
%w(delete delete_at shift slice! unshift).each do |method_name|
|
||||
define_array_wrapper_method(method_name)
|
||||
end
|
||||
|
||||
|
||||
%w(collect! compact! delete_if fill flatten! insert reverse!
|
||||
rotate! select! shuffle! sort! sort_by! uniq!).each do |method_name|
|
||||
define_array_wrapper_with_result_method(method_name)
|
||||
end
|
||||
alias_method :keep_if, :select!
|
||||
alias_method :map!, :collect!
|
||||
alias_method :reject!, :delete_if
|
||||
|
||||
|
||||
# propagates changes made by user of enumerator back to the original repeated field.
|
||||
# This only applies in cases where the calling function which created the enumerator,
|
||||
# such as #sort!, modifies itself rather than a new array, such as #sort
|
||||
class ProxyingEnumerator < Struct.new(:repeated_field, :external_enumerator)
|
||||
def each(*args, &block)
|
||||
results = []
|
||||
external_enumerator.each_with_index do |val, i|
|
||||
result = yield(val)
|
||||
results << result
|
||||
#nil means no change occurred from yield; usually occurs when #to_a is called
|
||||
if result
|
||||
repeated_field[i] = result if result != val
|
||||
end
|
||||
end
|
||||
results
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
240
deps/protobuf/ruby/lib/google/protobuf/well_known_types.rb
vendored
Normal file
240
deps/protobuf/ruby/lib/google/protobuf/well_known_types.rb
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
#!/usr/bin/ruby
|
||||
# Protocol Buffers - Google's data interchange format
|
||||
# Copyright 2008 Google Inc. All rights reserved.
|
||||
# https://developers.google.com/protocol-buffers/
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following disclaimer
|
||||
# in the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'google/protobuf/any_pb'
|
||||
require 'google/protobuf/duration_pb'
|
||||
require 'google/protobuf/field_mask_pb'
|
||||
require 'google/protobuf/struct_pb'
|
||||
require 'google/protobuf/timestamp_pb'
|
||||
|
||||
module Google
|
||||
module Protobuf
|
||||
|
||||
Any.class_eval do
|
||||
def self.pack(msg, type_url_prefix='type.googleapis.com/')
|
||||
any = self.new
|
||||
any.pack(msg, type_url_prefix)
|
||||
any
|
||||
end
|
||||
|
||||
def pack(msg, type_url_prefix='type.googleapis.com/')
|
||||
if type_url_prefix.empty? or type_url_prefix[-1] != '/' then
|
||||
self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}"
|
||||
else
|
||||
self.type_url = "#{type_url_prefix}#{msg.class.descriptor.name}"
|
||||
end
|
||||
self.value = msg.to_proto
|
||||
end
|
||||
|
||||
def unpack(klass)
|
||||
if self.is(klass) then
|
||||
klass.decode(self.value)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def type_name
|
||||
return self.type_url.split("/")[-1]
|
||||
end
|
||||
|
||||
def is(klass)
|
||||
return self.type_name == klass.descriptor.name
|
||||
end
|
||||
end
|
||||
|
||||
Timestamp.class_eval do
|
||||
if RUBY_VERSION < "2.5"
|
||||
def to_time
|
||||
Time.at(self.to_f)
|
||||
end
|
||||
else
|
||||
def to_time
|
||||
Time.at(seconds, nanos, :nanosecond)
|
||||
end
|
||||
end
|
||||
|
||||
def self.from_time(time)
|
||||
new.from_time(time)
|
||||
end
|
||||
|
||||
def from_time(time)
|
||||
self.seconds = time.to_i
|
||||
self.nanos = time.nsec
|
||||
self
|
||||
end
|
||||
|
||||
def to_i
|
||||
self.seconds
|
||||
end
|
||||
|
||||
def to_f
|
||||
self.seconds + (self.nanos.quo(1_000_000_000))
|
||||
end
|
||||
end
|
||||
|
||||
Duration.class_eval do
|
||||
def to_f
|
||||
self.seconds + (self.nanos.to_f / 1_000_000_000)
|
||||
end
|
||||
end
|
||||
|
||||
class UnexpectedStructType < Google::Protobuf::Error; end
|
||||
|
||||
Value.class_eval do
|
||||
def to_ruby(recursive = false)
|
||||
case self.kind
|
||||
when :struct_value
|
||||
if recursive
|
||||
self.struct_value.to_h
|
||||
else
|
||||
self.struct_value
|
||||
end
|
||||
when :list_value
|
||||
if recursive
|
||||
self.list_value.to_a
|
||||
else
|
||||
self.list_value
|
||||
end
|
||||
when :null_value
|
||||
nil
|
||||
when :number_value
|
||||
self.number_value
|
||||
when :string_value
|
||||
self.string_value
|
||||
when :bool_value
|
||||
self.bool_value
|
||||
else
|
||||
raise UnexpectedStructType
|
||||
end
|
||||
end
|
||||
|
||||
def self.from_ruby(value)
|
||||
self.new.from_ruby(value)
|
||||
end
|
||||
|
||||
def from_ruby(value)
|
||||
case value
|
||||
when NilClass
|
||||
self.null_value = :NULL_VALUE
|
||||
when Numeric
|
||||
self.number_value = value
|
||||
when String
|
||||
self.string_value = value
|
||||
when TrueClass
|
||||
self.bool_value = true
|
||||
when FalseClass
|
||||
self.bool_value = false
|
||||
when Struct
|
||||
self.struct_value = value
|
||||
when Hash
|
||||
self.struct_value = Struct.from_hash(value)
|
||||
when ListValue
|
||||
self.list_value = value
|
||||
when Array
|
||||
self.list_value = ListValue.from_a(value)
|
||||
else
|
||||
raise UnexpectedStructType
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
Struct.class_eval do
|
||||
def [](key)
|
||||
self.fields[key].to_ruby
|
||||
rescue NoMethodError
|
||||
nil
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
unless key.is_a?(String)
|
||||
raise UnexpectedStructType, "Struct keys must be strings."
|
||||
end
|
||||
self.fields[key] ||= Google::Protobuf::Value.new
|
||||
self.fields[key].from_ruby(value)
|
||||
end
|
||||
|
||||
def to_h
|
||||
ret = {}
|
||||
self.fields.each { |key, val| ret[key] = val.to_ruby(true) }
|
||||
ret
|
||||
end
|
||||
|
||||
def self.from_hash(hash)
|
||||
ret = Struct.new
|
||||
hash.each { |key, val| ret[key] = val }
|
||||
ret
|
||||
end
|
||||
|
||||
def has_key?(key)
|
||||
self.fields.has_key?(key)
|
||||
end
|
||||
end
|
||||
|
||||
ListValue.class_eval do
|
||||
include Enumerable
|
||||
|
||||
def length
|
||||
self.values.length
|
||||
end
|
||||
|
||||
def [](index)
|
||||
self.values[index].to_ruby
|
||||
end
|
||||
|
||||
def []=(index, value)
|
||||
self.values[index].from_ruby(value)
|
||||
end
|
||||
|
||||
def <<(value)
|
||||
wrapper = Google::Protobuf::Value.new
|
||||
wrapper.from_ruby(value)
|
||||
self.values << wrapper
|
||||
end
|
||||
|
||||
def each
|
||||
self.values.each { |x| yield(x.to_ruby) }
|
||||
end
|
||||
|
||||
def to_a
|
||||
self.values.map { |x| x.to_ruby(true) }
|
||||
end
|
||||
|
||||
def self.from_a(arr)
|
||||
ret = ListValue.new
|
||||
arr.each { |val| ret << val }
|
||||
ret
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user