protobuf-core 3.5.0

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.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +18 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +23 -0
  8. data/Rakefile +5 -0
  9. data/bin/protoc-gen-ruby +16 -0
  10. data/lib/protobuf.rb +27 -0
  11. data/lib/protobuf/code_generator.rb +44 -0
  12. data/lib/protobuf/core.rb +2 -0
  13. data/lib/protobuf/core/version.rb +5 -0
  14. data/lib/protobuf/decoder.rb +73 -0
  15. data/lib/protobuf/deprecation.rb +112 -0
  16. data/lib/protobuf/descriptors.rb +3 -0
  17. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +54 -0
  18. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +251 -0
  19. data/lib/protobuf/encoder.rb +67 -0
  20. data/lib/protobuf/enum.rb +303 -0
  21. data/lib/protobuf/exceptions.rb +9 -0
  22. data/lib/protobuf/field.rb +74 -0
  23. data/lib/protobuf/field/base_field.rb +267 -0
  24. data/lib/protobuf/field/bool_field.rb +59 -0
  25. data/lib/protobuf/field/bytes_field.rb +82 -0
  26. data/lib/protobuf/field/double_field.rb +25 -0
  27. data/lib/protobuf/field/enum_field.rb +68 -0
  28. data/lib/protobuf/field/field_array.rb +87 -0
  29. data/lib/protobuf/field/fixed32_field.rb +25 -0
  30. data/lib/protobuf/field/fixed64_field.rb +28 -0
  31. data/lib/protobuf/field/float_field.rb +41 -0
  32. data/lib/protobuf/field/int32_field.rb +21 -0
  33. data/lib/protobuf/field/int64_field.rb +21 -0
  34. data/lib/protobuf/field/integer_field.rb +23 -0
  35. data/lib/protobuf/field/message_field.rb +65 -0
  36. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  37. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  38. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  39. data/lib/protobuf/field/sint32_field.rb +21 -0
  40. data/lib/protobuf/field/sint64_field.rb +21 -0
  41. data/lib/protobuf/field/string_field.rb +34 -0
  42. data/lib/protobuf/field/uint32_field.rb +21 -0
  43. data/lib/protobuf/field/uint64_field.rb +21 -0
  44. data/lib/protobuf/field/varint_field.rb +73 -0
  45. data/lib/protobuf/generators/base.rb +70 -0
  46. data/lib/protobuf/generators/enum_generator.rb +41 -0
  47. data/lib/protobuf/generators/extension_generator.rb +27 -0
  48. data/lib/protobuf/generators/field_generator.rb +131 -0
  49. data/lib/protobuf/generators/file_generator.rb +132 -0
  50. data/lib/protobuf/generators/group_generator.rb +105 -0
  51. data/lib/protobuf/generators/message_generator.rb +98 -0
  52. data/lib/protobuf/generators/printable.rb +160 -0
  53. data/lib/protobuf/logging.rb +39 -0
  54. data/lib/protobuf/message.rb +193 -0
  55. data/lib/protobuf/message/fields.rb +133 -0
  56. data/lib/protobuf/message/serialization.rb +89 -0
  57. data/lib/protobuf/optionable.rb +23 -0
  58. data/lib/protobuf/wire_type.rb +10 -0
  59. data/proto/dynamic_discovery.proto +44 -0
  60. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  61. data/proto/google/protobuf/descriptor.proto +620 -0
  62. data/proto/rpc.proto +62 -0
  63. data/protobuf-core.gemspec +31 -0
  64. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  65. data/spec/data/data.bin +3 -0
  66. data/spec/data/types.bin +0 -0
  67. data/spec/encoding/all_types_spec.rb +105 -0
  68. data/spec/encoding/extreme_values_spec.rb +0 -0
  69. data/spec/functional/class_inheritance_spec.rb +52 -0
  70. data/spec/functional/compile_and_require_spec.rb +29 -0
  71. data/spec/lib/protobuf/base_spec.rb +84 -0
  72. data/spec/lib/protobuf/code_generator_spec.rb +60 -0
  73. data/spec/lib/protobuf/enum_generator_spec.rb +73 -0
  74. data/spec/lib/protobuf/enum_spec.rb +265 -0
  75. data/spec/lib/protobuf/extension_generator_spec.rb +42 -0
  76. data/spec/lib/protobuf/field/bool_field_spec.rb +51 -0
  77. data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
  78. data/spec/lib/protobuf/field/float_field_spec.rb +55 -0
  79. data/spec/lib/protobuf/field/int32_field_spec.rb +90 -0
  80. data/spec/lib/protobuf/field/string_field_spec.rb +45 -0
  81. data/spec/lib/protobuf/field_generator_spec.rb +102 -0
  82. data/spec/lib/protobuf/field_spec.rb +191 -0
  83. data/spec/lib/protobuf/file_generator_spec.rb +32 -0
  84. data/spec/lib/protobuf/message_generator_spec.rb +0 -0
  85. data/spec/lib/protobuf/message_spec.rb +526 -0
  86. data/spec/lib/protobuf/optionable_spec.rb +46 -0
  87. data/spec/lib/protobuf_spec.rb +45 -0
  88. data/spec/spec_helper.rb +9 -0
  89. data/spec/support/packed_field.rb +22 -0
  90. data/spec/support/test/all_types.data.bin +0 -0
  91. data/spec/support/test/all_types.data.txt +119 -0
  92. data/spec/support/test/bacon.proto +14 -0
  93. data/spec/support/test/defaults.pb.rb +27 -0
  94. data/spec/support/test/defaults.proto +9 -0
  95. data/spec/support/test/enum.pb.rb +61 -0
  96. data/spec/support/test/enum.proto +34 -0
  97. data/spec/support/test/extended.pb.rb +24 -0
  98. data/spec/support/test/extended.proto +10 -0
  99. data/spec/support/test/extreme_values.data.bin +0 -0
  100. data/spec/support/test/google_unittest.pb.rb +530 -0
  101. data/spec/support/test/google_unittest.proto +713 -0
  102. data/spec/support/test/google_unittest_import.pb.rb +39 -0
  103. data/spec/support/test/google_unittest_import.proto +64 -0
  104. data/spec/support/test/google_unittest_import_public.pb.rb +10 -0
  105. data/spec/support/test/google_unittest_import_public.proto +38 -0
  106. data/spec/support/test/multi_field_extensions.pb.rb +58 -0
  107. data/spec/support/test/multi_field_extensions.proto +33 -0
  108. data/spec/support/test/resource.pb.rb +106 -0
  109. data/spec/support/test/resource.proto +94 -0
  110. metadata +306 -0
@@ -0,0 +1,29 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class SignedIntegerField < VarintField
6
+
7
+ ##
8
+ # Public Instance Methods
9
+ #
10
+
11
+ def decode(value)
12
+ if (value & 1).zero?
13
+ value >> 1 # positive value
14
+ else
15
+ ~value >> 1 # negative value
16
+ end
17
+ end
18
+
19
+ def encode(value)
20
+ if value >= 0
21
+ VarintField.encode(value << 1)
22
+ else
23
+ VarintField.encode(~(value << 1))
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require 'protobuf/field/signed_integer_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class Sint32Field < SignedIntegerField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.max
12
+ INT32_MAX
13
+ end
14
+
15
+ def self.min
16
+ INT32_MIN
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'protobuf/field/signed_integer_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class Sint64Field < SignedIntegerField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.max
12
+ INT64_MAX
13
+ end
14
+
15
+ def self.min
16
+ INT64_MIN
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ require 'protobuf/field/bytes_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class StringField < BytesField
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+
11
+ ENCODING = Encoding::UTF_8
12
+
13
+ ##
14
+ # Public Instance Methods
15
+ #
16
+
17
+ def decode(bytes)
18
+ bytes_to_decode = bytes.dup
19
+ bytes_to_decode.force_encoding(::Protobuf::Field::StringField::ENCODING)
20
+ bytes_to_decode
21
+ end
22
+
23
+ def encode(value)
24
+ value_to_encode = value.dup
25
+ value_to_encode.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
26
+ value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
27
+
28
+ string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
29
+ string_size << value_to_encode
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class Uint32Field < VarintField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.max
12
+ UINT32_MAX
13
+ end
14
+
15
+ def self.min
16
+ 0
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'protobuf/field/varint_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class Uint64Field < VarintField
6
+
7
+ ##
8
+ # Class Methods
9
+ #
10
+
11
+ def self.max
12
+ UINT64_MAX
13
+ end
14
+
15
+ def self.min
16
+ 0
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,73 @@
1
+ require 'protobuf/field/base_field'
2
+
3
+ module Protobuf
4
+ module Field
5
+ class VarintField < BaseField
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+
11
+ INT32_MAX = 2**31 - 1
12
+ INT32_MIN = -2**31
13
+ INT64_MAX = 2**63 - 1
14
+ INT64_MIN = -2**63
15
+ UINT32_MAX = 2**32 - 1
16
+ UINT64_MAX = 2**64 - 1
17
+
18
+ ##
19
+ # Class Methods
20
+ #
21
+
22
+ def self.default
23
+ 0
24
+ end
25
+
26
+ def self.encode(value)
27
+ bytes = []
28
+ until value < 128
29
+ bytes << (0x80 | (value & 0x7f))
30
+ value >>= 7
31
+ end
32
+ (bytes << value).pack('C*')
33
+ end
34
+
35
+ ##
36
+ # Public Instance Methods
37
+ #
38
+
39
+ def acceptable?(val)
40
+ int_val = coerce!(val)
41
+ int_val >= self.class.min && int_val <= self.class.max
42
+ rescue
43
+ false
44
+ end
45
+
46
+ def coerce!(val)
47
+ return val.to_i if val.is_a?(Numeric)
48
+ Integer(val, 10)
49
+ end
50
+
51
+ def decode(value)
52
+ value
53
+ end
54
+
55
+ def encode(value)
56
+ return [value].pack('C') if value < 128
57
+
58
+ bytes = []
59
+ until value == 0
60
+ bytes << (0x80 | (value & 0x7f))
61
+ value >>= 7
62
+ end
63
+ bytes[-1] &= 0x7f
64
+ bytes.pack('C*')
65
+ end
66
+
67
+ def wire_type
68
+ ::Protobuf::WireType::VARINT
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,70 @@
1
+ require 'protobuf/generators/printable'
2
+
3
+ module Protobuf
4
+ module Generators
5
+ class Base
6
+ include ::Protobuf::Generators::Printable
7
+
8
+ def self.validate_tags(type_name, tags)
9
+ return if tags.empty?
10
+
11
+ unique_tags = tags.uniq
12
+
13
+ if unique_tags.size < tags.size
14
+ ::Protobuf::CodeGenerator.fatal("#{type_name} object has duplicate tags. Expected #{unique_tags.size} tags, but got #{tags.size}. Suppress with PB_NO_TAG_WARNINGS=1.")
15
+ end
16
+
17
+ unless ENV.key?('PB_NO_TAG_WARNINGS')
18
+ range = (tags.min)..(tags.max)
19
+ if range.respond_to?(:size)
20
+ expected_size = range.size
21
+ else
22
+ expected_size = range.to_a.size
23
+ end
24
+
25
+ if tags.size < expected_size
26
+ ::Protobuf::CodeGenerator.print_tag_warning_suppress
27
+ ::Protobuf::CodeGenerator.warn("#{type_name} object should have #{expected_size} tags (#{range.begin}..#{range.end}), but found #{tags.size} tags.")
28
+ end
29
+ end
30
+ end
31
+
32
+ attr_reader :descriptor, :namespace, :options
33
+
34
+ def initialize(descriptor, indent_level = 0, options = {})
35
+ @descriptor = descriptor
36
+ @options = options
37
+ @namespace = @options.fetch(:namespace) { [] }
38
+ init_printer(indent_level)
39
+ end
40
+
41
+ def fully_qualified_type_namespace
42
+ ".#{type_namespace.join('.')}"
43
+ end
44
+
45
+ def run_once(label, &block)
46
+ tracker_ivar = "@_#{label}_compiled"
47
+ value_ivar = "@_#{label}_compiled_value"
48
+
49
+ if instance_variable_get(tracker_ivar)
50
+ return instance_variable_get(value_ivar)
51
+ else
52
+ return_value = block.call
53
+ instance_variable_set(tracker_ivar, true)
54
+ instance_variable_set(value_ivar, return_value)
55
+ return return_value
56
+ end
57
+ end
58
+
59
+ def to_s
60
+ compile
61
+ print_contents # see Printable
62
+ end
63
+
64
+ def type_namespace
65
+ @type_namespace ||= @namespace + [descriptor.name]
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,41 @@
1
+ require 'protobuf/generators/base'
2
+
3
+ module Protobuf
4
+ module Generators
5
+ class EnumGenerator < Base
6
+
7
+ def allow_alias?
8
+ descriptor.options.try(:allow_alias!) { false }
9
+ end
10
+
11
+ def compile
12
+ run_once(:compile) do
13
+ tags = []
14
+
15
+ print_class(descriptor.name, :enum) do
16
+ if allow_alias?
17
+ puts "set_option :allow_alias"
18
+ puts
19
+ end
20
+
21
+ descriptor.value.each do |enum_value_descriptor|
22
+ tags << enum_value_descriptor.number
23
+ puts build_value(enum_value_descriptor)
24
+ end
25
+ end
26
+
27
+ unless allow_alias?
28
+ self.class.validate_tags(fully_qualified_type_namespace, tags)
29
+ end
30
+ end
31
+ end
32
+
33
+ def build_value(enum_value_descriptor)
34
+ name = enum_value_descriptor.name
35
+ number = enum_value_descriptor.number
36
+ "define :#{name}, #{number}"
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ require 'protobuf/generators/base'
2
+ require 'protobuf/generators/group_generator'
3
+
4
+ module Protobuf
5
+ module Generators
6
+ class ExtensionGenerator < Base
7
+
8
+ def initialize(message_type, field_descriptors, indent_level)
9
+ super(nil, indent_level)
10
+ @message_type = modulize(message_type)
11
+ @field_descriptors = field_descriptors
12
+ end
13
+
14
+ def compile
15
+ run_once(:compile) do
16
+ print_class(@message_type, :message) do
17
+ group = GroupGenerator.new(current_indent)
18
+ group.add_extension_fields(@field_descriptors)
19
+ group.order = [:extension_field]
20
+ print group.to_s
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,131 @@
1
+ require 'protobuf/generators/base'
2
+
3
+ module Protobuf
4
+ module Generators
5
+ class FieldGenerator < Base
6
+
7
+ ##
8
+ # Constants
9
+ #
10
+ PROTO_INFINITY_DEFAULT = /^inf$/i.freeze
11
+ PROTO_NEGATIVE_INFINITY_DEFAULT = /^-inf$/i.freeze
12
+ PROTO_NAN_DEFAULT = /^nan$/i.freeze
13
+ RUBY_INFINITY_DEFAULT = '::Float::INFINITY'.freeze
14
+ RUBY_NEGATIVE_INFINITY_DEFAULT = '-::Float::INFINITY'.freeze
15
+ RUBY_NAN_DEFAULT = '::Float::NAN'.freeze
16
+
17
+ ##
18
+ # Attributes
19
+ #
20
+ attr_reader :field_options
21
+
22
+ def applicable_options
23
+ @applicable_options ||= field_options.map { |k, v| ":#{k} => #{v}" }
24
+ end
25
+
26
+ def default_value
27
+ @default_value ||= begin
28
+ if defaulted?
29
+ case descriptor.type.name
30
+ when :TYPE_ENUM then
31
+ enum_default_value
32
+ when :TYPE_STRING, :TYPE_BYTES then
33
+ string_default_value
34
+ when :TYPE_FLOAT, :TYPE_DOUBLE then
35
+ float_double_default_value
36
+ else
37
+ verbatim_default_value
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def defaulted?
44
+ descriptor.respond_to_has_and_present?(:default_value)
45
+ end
46
+
47
+ def deprecated?
48
+ descriptor.options.try(:deprecated?) { false }
49
+ end
50
+
51
+ def extension?
52
+ descriptor.respond_to_has_and_present?(:extendee)
53
+ end
54
+
55
+ def compile
56
+ run_once(:compile) do
57
+ field_definition = ["#{label} #{type_name}", name, number, applicable_options]
58
+ puts field_definition.flatten.compact.join(', ')
59
+ end
60
+ end
61
+
62
+ def label
63
+ @label ||= descriptor.label.name.to_s.downcase.sub(/label_/, '') # required, optional, repeated
64
+ end
65
+
66
+ def name
67
+ @name ||= ":#{descriptor.name}"
68
+ end
69
+
70
+ def number
71
+ @number ||= descriptor.number
72
+ end
73
+
74
+ def field_options
75
+ @field_options ||= begin
76
+ opts = {}
77
+ opts[:default] = default_value if defaulted?
78
+ opts[:packed] = 'true' if packed?
79
+ opts[:deprecated] = 'true' if deprecated?
80
+ opts[:extension] = 'true' if extension?
81
+ opts
82
+ end
83
+ end
84
+
85
+ def packed?
86
+ descriptor.options.try(:packed?) { false }
87
+ end
88
+
89
+ # Determine the field type
90
+ def type_name
91
+ @type_name ||= begin
92
+ case descriptor.type.name
93
+ when :TYPE_MESSAGE, :TYPE_ENUM, :TYPE_GROUP then
94
+ modulize(descriptor.type_name)
95
+ else
96
+ type_name = descriptor.type.name.to_s.downcase.sub(/type_/, '')
97
+ ":#{type_name}"
98
+ end
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def enum_default_value
105
+ "#{type_name}::#{verbatim_default_value}"
106
+ end
107
+
108
+ def float_double_default_value
109
+ case verbatim_default_value
110
+ when PROTO_INFINITY_DEFAULT then
111
+ RUBY_INFINITY_DEFAULT
112
+ when PROTO_NEGATIVE_INFINITY_DEFAULT then
113
+ RUBY_NEGATIVE_INFINITY_DEFAULT
114
+ when PROTO_NAN_DEFAULT then
115
+ RUBY_NAN_DEFAULT
116
+ else
117
+ verbatim_default_value
118
+ end
119
+ end
120
+
121
+ def string_default_value
122
+ %("#{verbatim_default_value.gsub(/'/, '\\\\\'')}")
123
+ end
124
+
125
+ def verbatim_default_value
126
+ descriptor.default_value
127
+ end
128
+
129
+ end
130
+ end
131
+ end