protobuf 3.7.0.pre2 → 3.7.0.pre3

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/.rubocop_todo.yml +7 -1
  4. data/.travis.yml +8 -1
  5. data/CHANGES.md +25 -1
  6. data/bin/protoc-gen-ruby +2 -2
  7. data/lib/protobuf/cli.rb +29 -17
  8. data/lib/protobuf/code_generator.rb +49 -1
  9. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +9 -1
  10. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +14 -1
  11. data/lib/protobuf/encoder.rb +2 -2
  12. data/lib/protobuf/enum.rb +3 -3
  13. data/lib/protobuf/field/base_field.rb +27 -19
  14. data/lib/protobuf/field/bool_field.rb +10 -8
  15. data/lib/protobuf/field/bytes_field.rb +14 -6
  16. data/lib/protobuf/field/float_field.rb +2 -0
  17. data/lib/protobuf/field/string_field.rb +10 -0
  18. data/lib/protobuf/field/varint_field.rb +12 -2
  19. data/lib/protobuf/generators/base.rb +29 -14
  20. data/lib/protobuf/generators/enum_generator.rb +4 -7
  21. data/lib/protobuf/generators/field_generator.rb +17 -4
  22. data/lib/protobuf/generators/file_generator.rb +121 -10
  23. data/lib/protobuf/generators/group_generator.rb +9 -3
  24. data/lib/protobuf/generators/message_generator.rb +8 -2
  25. data/lib/protobuf/generators/option_generator.rb +17 -0
  26. data/lib/protobuf/generators/printable.rb +2 -2
  27. data/lib/protobuf/generators/service_generator.rb +27 -3
  28. data/lib/protobuf/lifecycle.rb +1 -1
  29. data/lib/protobuf/message/fields.rb +13 -15
  30. data/lib/protobuf/message/serialization.rb +9 -9
  31. data/lib/protobuf/message.rb +23 -29
  32. data/lib/protobuf/optionable.rb +10 -10
  33. data/lib/protobuf/rpc/buffer.rb +7 -6
  34. data/lib/protobuf/rpc/client.rb +2 -30
  35. data/lib/protobuf/rpc/connectors/base.rb +168 -6
  36. data/lib/protobuf/rpc/connectors/ping.rb +2 -2
  37. data/lib/protobuf/rpc/connectors/socket.rb +6 -1
  38. data/lib/protobuf/rpc/connectors/zmq.rb +1 -2
  39. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +2 -1
  40. data/lib/protobuf/rpc/error.rb +2 -2
  41. data/lib/protobuf/rpc/middleware/exception_handler.rb +4 -0
  42. data/lib/protobuf/rpc/middleware/logger.rb +4 -0
  43. data/lib/protobuf/rpc/middleware/request_decoder.rb +11 -16
  44. data/lib/protobuf/rpc/middleware/response_encoder.rb +18 -23
  45. data/lib/protobuf/rpc/rpc.pb.rb +2 -1
  46. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  47. data/lib/protobuf/rpc/servers/socket/server.rb +4 -4
  48. data/lib/protobuf/rpc/servers/socket_runner.rb +8 -0
  49. data/lib/protobuf/rpc/servers/zmq/broker.rb +7 -6
  50. data/lib/protobuf/rpc/servers/zmq/server.rb +8 -7
  51. data/lib/protobuf/rpc/servers/zmq/util.rb +6 -6
  52. data/lib/protobuf/rpc/servers/zmq/worker.rb +7 -6
  53. data/lib/protobuf/rpc/servers/zmq_runner.rb +8 -0
  54. data/lib/protobuf/rpc/service.rb +6 -15
  55. data/lib/protobuf/rpc/service_directory.rb +1 -1
  56. data/lib/protobuf/rpc/service_dispatcher.rb +5 -6
  57. data/lib/protobuf/rpc/service_filters.rb +8 -30
  58. data/lib/protobuf/socket.rb +2 -2
  59. data/lib/protobuf/version.rb +1 -1
  60. data/lib/protobuf/zmq.rb +2 -2
  61. data/lib/protobuf.rb +12 -27
  62. data/protobuf.gemspec +5 -3
  63. data/spec/benchmark/tasks.rb +1 -0
  64. data/spec/functional/code_generator_spec.rb +38 -0
  65. data/spec/lib/protobuf/cli_spec.rb +19 -10
  66. data/spec/lib/protobuf/code_generator_spec.rb +28 -0
  67. data/spec/lib/protobuf/enum_spec.rb +6 -2
  68. data/spec/lib/protobuf/field/bool_field_spec.rb +4 -0
  69. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  70. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  71. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  72. data/spec/lib/protobuf/field/float_field_spec.rb +5 -1
  73. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  74. data/spec/lib/protobuf/field/message_field_spec.rb +53 -0
  75. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  76. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  77. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  78. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  79. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  80. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  81. data/spec/lib/protobuf/generators/base_spec.rb +69 -1
  82. data/spec/lib/protobuf/generators/enum_generator_spec.rb +1 -1
  83. data/spec/lib/protobuf/generators/field_generator_spec.rb +58 -0
  84. data/spec/lib/protobuf/generators/file_generator_spec.rb +47 -0
  85. data/spec/lib/protobuf/generators/service_generator_spec.rb +58 -14
  86. data/spec/lib/protobuf/message_spec.rb +2 -2
  87. data/spec/lib/protobuf/optionable_spec.rb +96 -0
  88. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +151 -0
  89. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +3 -3
  90. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +0 -2
  91. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +2 -2
  92. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +4 -4
  93. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +2 -2
  94. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +1 -18
  95. data/spec/lib/protobuf/rpc/service_filters_spec.rb +2 -2
  96. data/spec/lib/protobuf/varint_spec.rb +1 -1
  97. data/spec/lib/protobuf_spec.rb +13 -16
  98. data/spec/support/packed_field.rb +3 -2
  99. data/spec/support/protos/enum.pb.rb +2 -1
  100. data/spec/support/protos/enum.proto +1 -0
  101. data/spec/support/protos/google_unittest.pb.rb +69 -58
  102. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  103. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  104. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  105. data/spec/support/protos/google_unittest_import.pb.rb +8 -0
  106. data/spec/support/protos/google_unittest_import_public.pb.rb +6 -0
  107. data/spec/support/protos/resource.pb.rb +54 -2
  108. data/spec/support/protos/resource.proto +42 -2
  109. data/spec/support/server.rb +1 -1
  110. metadata +39 -16
  111. data/lib/protobuf/rpc/connector.rb +0 -19
  112. data/lib/protobuf/rpc/connectors/common.rb +0 -176
  113. data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
  114. data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4eb324f0fa537308f4f06735a42fe4a73f1483e4
4
- data.tar.gz: e1067403611fd86bf86b064115cbd42651aa68d5
3
+ metadata.gz: f7811480fd5acc23cbffe64a18fa86ae89e0db34
4
+ data.tar.gz: f6b6a43c768bde92332c8b4c3ec6643cfc8e1b47
5
5
  SHA512:
6
- metadata.gz: 74422c44f167336cb16897fbe21c77eb89f663f5e4217759eff2499ef2889fffd05529f49ef1586378927b23919f7d97d41bc69b9e187694a72366ddb2bff234
7
- data.tar.gz: 9a5436e3e9ead8917e9cff660674494a31e6522d4ba53b9ea31c6ad1643b946507dc947c5878678eda997ae2c70543e71923e7b2727b8801c527754bdc71dac4
6
+ metadata.gz: 5484610ee1505ef341309a57cd3194dbf887b1034778497a90caecbc427e06fe21f6a033a361e9483e5fde906b2799c4d933e85b7661b01fe5f61c35e5fea4c0
7
+ data.tar.gz: daa702e3dce267e5c39a6569f42dd34ad62bb9208a897e5c7703833fc8556da1e2b1006b2138f8a679a6234a34dbf1051ac4a073f20e9c3eedbab9897caba8b9
data/.rubocop.yml CHANGED
@@ -2,6 +2,8 @@ inherit_from: .rubocop_todo.yml
2
2
 
3
3
  AllCops:
4
4
  DisplayCopNames: true
5
+ Exclude:
6
+ - 'spec/support/protos/*.pb.rb'
5
7
 
6
8
  Lint/EndAlignment:
7
9
  AlignWith: keyword
@@ -56,7 +58,10 @@ Style/TrailingBlankLines:
56
58
  Exclude:
57
59
  - '**/*.pb.rb'
58
60
 
59
- Style/TrailingComma:
61
+ Style/TrailingCommaInArguments:
62
+ EnforcedStyleForMultiline: comma
63
+
64
+ Style/TrailingCommaInLiteral:
60
65
  EnforcedStyleForMultiline: comma
61
66
 
62
67
  Style/TrivialAccessors:
data/.rubocop_todo.yml CHANGED
@@ -43,6 +43,9 @@ Performance/StringReplacement:
43
43
  Exclude:
44
44
  - 'lib/protobuf/rpc/buffer.rb'
45
45
 
46
+ Performance/TimesMap:
47
+ Enabled: false
48
+
46
49
  # Offense count: 127
47
50
  # Configuration parameters: Exclude.
48
51
  Style/Documentation:
@@ -113,6 +116,9 @@ Style/ExtraSpacing:
113
116
  Style/NumericLiterals:
114
117
  MinDigits: 21
115
118
 
119
+ Style/SignalException:
120
+ Enabled: false
121
+
116
122
  # Offense count: 473
117
123
  # Cop supports --auto-correct.
118
124
  # Configuration parameters: EnforcedStyle, SupportedStyles.
@@ -136,4 +142,4 @@ Style/SymbolProc:
136
142
  # Cop supports --auto-correct.
137
143
  # Configuration parameters: WordRegex.
138
144
  Style/WordArray:
139
- MinSize: 2
145
+ MinSize: 4
data/.travis.yml CHANGED
@@ -2,6 +2,11 @@ before_install:
2
2
  - sudo apt-get update -qq
3
3
  - sudo apt-get install -y libzmq3-dev
4
4
  - sudo -E ./install-protobuf.sh
5
+ - java -Xmx1g -version
6
+ - javac -J-Xmx1g -version
7
+ - export JRUBY_OPTS=-J-Xmx1g
8
+ # Required for rainbow installation issue, https://github.com/sickill/rainbow/issues/44
9
+ - gem update --system
5
10
  - gem update bundler
6
11
  language: ruby
7
12
  rvm:
@@ -9,7 +14,9 @@ rvm:
9
14
  - 2.0.0
10
15
  - 2.1
11
16
  - 2.2
12
- - jruby
17
+ - 2.2.2
18
+ - 2.3
19
+ - jruby-9.1.7.0
13
20
  - rbx-2
14
21
  env:
15
22
  - PROTOBUF_VERSION=2.6.1
data/CHANGES.md CHANGED
@@ -1,4 +1,26 @@
1
- # Stable (3.x)
1
+ # Beta (3.7.x)
2
+
3
+ 3.7.0 (pre3)
4
+ -----------
5
+ - Evaluate extension fields in code generation (#329)
6
+ - Change the ping port to use ms timeout and make the default 200ms (#332)
7
+ - Fix build failures caused by Rails 5 requirement of Ruby 2.2.2 (#343)
8
+ - Add functional tests (#346)
9
+ - Extract client and server (#347) (#348)
10
+ - BUG: Fix decoding of packed fields (#349)
11
+ - Add support for custom file options (#350)
12
+ - BUG: enum_for_tags returns nil if tag nil (#352)
13
+ - Update rubocop and fix cops (#353)
14
+ - Optimization for varint (#356)
15
+ - Add support for custom field options (#357)
16
+ - Add support for custom enum options (#359)
17
+ - Add support for custom message options (#360)
18
+ - Acceptable check is not needed most places as coerce runs the same logic (#361)
19
+ - Encode straight to stream without intermediary copies (#362)
20
+ - Move dynamic rule checks to the initialize method (#363)
21
+ - Add support for custom service options (#364)
22
+ - Add support for custom method options (#365)
23
+ - Upcase enum default (#366)
2
24
 
3
25
  3.7.0 (pre2)
4
26
  -----------
@@ -20,6 +42,8 @@
20
42
  - Refresh google/protobuf/descriptor.{proto,pb.rb}
21
43
  - Properly encode and decode negative enum values.
22
44
 
45
+ # Stable (3.6.x)
46
+
23
47
  3.6.9
24
48
  --------
25
49
  - Make protobuf serivce directory pluggable.
data/bin/protoc-gen-ruby CHANGED
@@ -18,5 +18,5 @@ STDOUT.binmode
18
18
 
19
19
  request_bytes = STDIN.read
20
20
  code_generator = ::Protobuf::CodeGenerator.new(request_bytes)
21
- response_bytes = code_generator.response_bytes
22
- STDOUT.print(response_bytes)
21
+ code_generator.eval_unknown_extensions!
22
+ STDOUT.print(code_generator.response_bytes)
data/lib/protobuf/cli.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/hash/keys'
2
+ require 'active_support/inflector'
2
3
 
3
4
  require 'thor'
4
5
  require 'protobuf/version'
@@ -71,11 +72,12 @@ module Protobuf
71
72
 
72
73
  # Tell protobuf how to handle the printing of deprecated field usage.
73
74
  def configure_deprecation_warnings
74
- if options.print_deprecation_warnings.nil?
75
- ::Protobuf.print_deprecation_warnings = !ENV.key?("PB_IGNORE_DEPRECATIONS")
76
- else
77
- ::Protobuf.print_deprecation_warnings = options.print_deprecation_warnings?
78
- end
75
+ ::Protobuf.print_deprecation_warnings =
76
+ if options.print_deprecation_warnings.nil?
77
+ !ENV.key?("PB_IGNORE_DEPRECATIONS")
78
+ else
79
+ options.print_deprecation_warnings?
80
+ end
79
81
  end
80
82
 
81
83
  # If we pause during request we don't need to pause in serialization
@@ -84,12 +86,13 @@ module Protobuf
84
86
 
85
87
  debug_say('Configuring gc')
86
88
 
87
- if defined?(JRUBY_VERSION)
88
- # GC.enable/disable are noop's on Jruby
89
- ::Protobuf.gc_pause_server_request = false
90
- else
91
- ::Protobuf.gc_pause_server_request = options.gc_pause_request?
92
- end
89
+ ::Protobuf.gc_pause_server_request =
90
+ if defined?(JRUBY_VERSION)
91
+ # GC.enable/disable are noop's on Jruby
92
+ false
93
+ else
94
+ options.gc_pause_request?
95
+ end
93
96
  end
94
97
 
95
98
  # Setup the protobuf logger.
@@ -114,6 +117,7 @@ module Protobuf
114
117
  # Configure the mode of the server and the runner class.
115
118
  def configure_runner_mode
116
119
  debug_say('Configuring runner mode')
120
+ server_type = ENV["PB_SERVER_TYPE"]
117
121
 
118
122
  self.mode = if multi_mode?
119
123
  say('WARNING: You have provided multiple mode options. Defaulting to socket mode.', :yellow)
@@ -121,14 +125,14 @@ module Protobuf
121
125
  elsif options.zmq?
122
126
  :zmq
123
127
  else
124
- case server_type = ENV["PB_SERVER_TYPE"]
125
- when nil, /socket/i
128
+ case server_type
129
+ when nil, /\Asocket[[:space:]]*\z/i
126
130
  :socket
127
- when /zmq/i
131
+ when /\Azmq[[:space:]]*\z/i
128
132
  :zmq
129
133
  else
130
- say "WARNING: You have provided incorrect option 'PB_SERVER_TYPE=#{server_type}'. Defaulting to socket mode.", :yellow
131
- :socket
134
+ require server_type.to_s
135
+ server_type
132
136
  end
133
137
  end
134
138
  end
@@ -160,7 +164,8 @@ module Protobuf
160
164
  when :socket
161
165
  create_socket_runner
162
166
  else
163
- say_and_exit("Unknown runner mode: #{mode}")
167
+ say("Extension runner mode: #{mode}")
168
+ create_extension_server_runner
164
169
  end
165
170
  end
166
171
 
@@ -206,6 +211,13 @@ module Protobuf
206
211
  exit(1)
207
212
  end
208
213
 
214
+ def create_extension_server_runner
215
+ classified = mode.classify
216
+ extension_server_class = classified.constantize
217
+
218
+ self.runner = extension_server_class.new(runner_options)
219
+ end
220
+
209
221
  def create_socket_runner
210
222
  require 'protobuf/socket'
211
223
 
@@ -1,3 +1,4 @@
1
+ require 'active_support/core_ext/module/aliasing'
1
2
  require 'protobuf/generators/file_generator'
2
3
 
3
4
  module Protobuf
@@ -11,7 +12,7 @@ module Protobuf
11
12
 
12
13
  def self.print_tag_warning_suppress
13
14
  STDERR.puts "Suppress tag warning output with PB_NO_TAG_WARNINGS=1."
14
- def self.print_tag_warning_suppress; end
15
+ def self.print_tag_warning_suppress; end # rubocop:disable Lint/DuplicateMethods, Lint/NestedMethodDefinition
15
16
  end
16
17
 
17
18
  def self.warn(message)
@@ -25,9 +26,17 @@ module Protobuf
25
26
  public
26
27
 
27
28
  def initialize(request_bytes)
29
+ @request_bytes = request_bytes
28
30
  self.request = ::Google::Protobuf::Compiler::CodeGeneratorRequest.decode(request_bytes)
29
31
  end
30
32
 
33
+ def eval_unknown_extensions!
34
+ request.proto_file.each do |file_descriptor|
35
+ ::Protobuf::Generators::FileGenerator.new(file_descriptor).eval_unknown_extensions!
36
+ end
37
+ self.request = ::Google::Protobuf::Compiler::CodeGeneratorRequest.decode(@request_bytes)
38
+ end
39
+
31
40
  def generate_file(file_descriptor)
32
41
  ::Protobuf::Generators::FileGenerator.new(file_descriptor).generate_output_file
33
42
  end
@@ -40,5 +49,44 @@ module Protobuf
40
49
  ::Google::Protobuf::Compiler::CodeGeneratorResponse.encode(:file => generated_files)
41
50
  end
42
51
 
52
+ Protobuf::Field::BaseField.module_eval do
53
+ # Sets a MessageField that is known to be an option.
54
+ # We must allow fields to be set one at a time, as option syntax allows us to
55
+ # set each field within the option using a separate "option" line.
56
+ def set_with_options(message_instance, bytes)
57
+ if message_instance[name].is_a?(::Protobuf::Message)
58
+ gp = Google::Protobuf
59
+ if message_instance.is_a?(gp::EnumOptions) || message_instance.is_a?(gp::EnumValueOptions) ||
60
+ message_instance.is_a?(gp::FieldOptions) || message_instance.is_a?(gp::FileOptions) ||
61
+ message_instance.is_a?(gp::MethodOptions) || message_instance.is_a?(gp::ServiceOptions) ||
62
+ message_instance.is_a?(gp::MessageOptions)
63
+
64
+ original_field = message_instance[name]
65
+ decoded_field = decode(bytes)
66
+ decoded_field.each_field do |subfield, subvalue|
67
+ option_set(original_field, subfield, subvalue) { decoded_field.field?(subfield.tag) }
68
+ end
69
+ return
70
+ end
71
+ end
72
+
73
+ set_without_options(message_instance, bytes)
74
+ end
75
+
76
+ def option_set(message_field, subfield, subvalue)
77
+ return unless yield
78
+ if subfield.repeated?
79
+ message_field[subfield.tag].concat(subvalue)
80
+ elsif message_field[subfield.tag] && subvalue.is_a?(::Protobuf::Message)
81
+ subvalue.each_field do |f, v|
82
+ option_set(message_field[subfield.tag], f, v) { subvalue.field?(f.tag) }
83
+ end
84
+ else
85
+ message_field[subfield.tag] = subvalue
86
+ end
87
+ end
88
+
89
+ alias_method_chain :set, :options
90
+ end
43
91
  end
44
92
  end
@@ -3,7 +3,7 @@
3
3
  ##
4
4
  # This file is auto-generated. DO NOT EDIT!
5
5
  #
6
- require 'protobuf/message'
6
+ require 'protobuf'
7
7
 
8
8
 
9
9
  ##
@@ -14,6 +14,7 @@ require 'google/protobuf/descriptor.pb'
14
14
  module Google
15
15
  module Protobuf
16
16
  module Compiler
17
+ ::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
17
18
 
18
19
  ##
19
20
  # Message Classes
@@ -26,6 +27,13 @@ module Google
26
27
 
27
28
 
28
29
 
30
+ ##
31
+ # File Options
32
+ #
33
+ set_option :java_package, "com.google.protobuf.compiler"
34
+ set_option :java_outer_classname, "PluginProtos"
35
+
36
+
29
37
  ##
30
38
  # Message Fields
31
39
  #
@@ -3,10 +3,11 @@
3
3
  ##
4
4
  # This file is auto-generated. DO NOT EDIT!
5
5
  #
6
- require 'protobuf/message'
6
+ require 'protobuf'
7
7
 
8
8
  module Google
9
9
  module Protobuf
10
+ ::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
10
11
 
11
12
  ##
12
13
  # Message Classes
@@ -95,6 +96,17 @@ module Google
95
96
 
96
97
 
97
98
 
99
+ ##
100
+ # File Options
101
+ #
102
+ set_option :java_package, "com.google.protobuf"
103
+ set_option :java_outer_classname, "DescriptorProtos"
104
+ set_option :optimize_for, ::Google::Protobuf::FileOptions::OptimizeMode::SPEED
105
+ set_option :go_package, "descriptor"
106
+ set_option :objc_class_prefix, "GPB"
107
+ set_option :csharp_namespace, "Google.Protobuf.Reflection"
108
+
109
+
98
110
  ##
99
111
  # Message Fields
100
112
  #
@@ -149,6 +161,7 @@ module Google
149
161
  optional :string, :extendee, 2
150
162
  optional :string, :default_value, 7
151
163
  optional :int32, :oneof_index, 9
164
+ optional :string, :json_name, 10
152
165
  optional ::Google::Protobuf::FieldOptions, :options, 8
153
166
  end
154
167
 
@@ -8,11 +8,11 @@ module Protobuf
8
8
  stream << "#{field.tag_encoded}#{::Protobuf::Field::VarintField.encode(packed_value.size)}#{packed_value}"
9
9
  else
10
10
  value.each do |val|
11
- stream << "#{field.tag_encoded}#{field.encode(val)}"
11
+ field.encode_to_stream(val, stream)
12
12
  end
13
13
  end
14
14
  else
15
- stream << "#{field.tag_encoded}#{field.encode(value)}"
15
+ field.encode_to_stream(value, stream)
16
16
  end
17
17
  end
18
18
 
data/lib/protobuf/enum.rb CHANGED
@@ -94,7 +94,7 @@ module Protobuf
94
94
  # Returns an array with zero or more Enum objects or nil.
95
95
  #
96
96
  def self.enums_for_tag(tag)
97
- mapped_enums[tag.to_i] || []
97
+ tag && mapped_enums[tag.to_i] || []
98
98
  end
99
99
 
100
100
  # Public: Get the Enum associated with the given name.
@@ -129,7 +129,7 @@ module Protobuf
129
129
  # Enums, the first enum defined will be returned.
130
130
  #
131
131
  def self.enum_for_tag(tag)
132
- (mapped_enums[tag.to_i] || []).first
132
+ tag && (mapped_enums[tag.to_i] || []).first
133
133
  end
134
134
 
135
135
  # Public: Get an Enum by a variety of type-checking mechanisms.
@@ -309,6 +309,6 @@ module Protobuf
309
309
  ##
310
310
  # Instance Aliases
311
311
  #
312
- alias_method :to_hash_value, :to_i
312
+ alias :to_hash_value to_i
313
313
  end
314
314
  end
@@ -1,3 +1,4 @@
1
+ require 'active_support/core_ext/hash/slice'
1
2
  require 'protobuf/field/field_array'
2
3
  module Protobuf
3
4
  module Field
@@ -39,7 +40,19 @@ module Protobuf
39
40
  @rule = rule
40
41
  @tag = tag
41
42
  @type_class = type_class
42
- @options = options
43
+ # Populate the option hash with all the original default field options, for backwards compatibility.
44
+ # However, both default and custom options should ideally be accessed through the Optionable .{get,get!}_option functions.
45
+ @options = options.slice(:ctype, :packed, :deprecated, :lazy, :jstype, :weak, :uninterpreted_option, :default, :extension)
46
+ options.each do |option_name, value|
47
+ set_option(option_name, value)
48
+ end
49
+
50
+ @extension = options.key?(:extension)
51
+ @deprecated = options.key?(:deprecated)
52
+ @required = rule == :required
53
+ @repeated = rule == :repeated
54
+ @optional = rule == :optional
55
+ @packed = @repeated && options.key?(:packed)
43
56
 
44
57
  validate_packed_field if packed?
45
58
  define_accessor(simple_name, fully_qualified_name) if simple_name
@@ -77,39 +90,39 @@ module Protobuf
77
90
  end
78
91
 
79
92
  def deprecated?
80
- options.key?(:deprecated)
93
+ @deprecated
81
94
  end
82
95
 
83
96
  def encode(_value)
84
97
  fail NotImplementedError, "#{self.class.name}##{__method__}"
85
98
  end
86
99
 
100
+ def encode_to_stream(value, stream)
101
+ stream << tag_encoded << encode(value)
102
+ end
103
+
87
104
  def extension?
88
- options.key?(:extension)
105
+ @extension
89
106
  end
90
107
 
91
108
  def enum?
92
109
  false
93
110
  end
94
111
 
95
- def getter
96
- name
97
- end
98
-
99
112
  def message?
100
113
  false
101
114
  end
102
115
 
103
116
  def optional?
104
- rule == :optional
117
+ @optional
105
118
  end
106
119
 
107
120
  def packed?
108
- repeated? && options.key?(:packed)
121
+ @packed
109
122
  end
110
123
 
111
124
  def repeated?
112
- rule == :repeated
125
+ @repeated
113
126
  end
114
127
 
115
128
  def repeated_message?
@@ -117,7 +130,7 @@ module Protobuf
117
130
  end
118
131
 
119
132
  def required?
120
- rule == :required
133
+ @required
121
134
  end
122
135
 
123
136
  # FIXME: need to cleanup (rename) this warthog of a method.
@@ -129,18 +142,14 @@ module Protobuf
129
142
  stream = StringIO.new(bytes)
130
143
 
131
144
  if wire_type == ::Protobuf::WireType::VARINT
132
- array << Varint.decode(stream) until stream.eof?
145
+ array << decode(Varint.decode(stream)) until stream.eof?
133
146
  elsif wire_type == ::Protobuf::WireType::FIXED64
134
- array << stream.read(8) until stream.eof?
147
+ array << decode(stream.read(8)) until stream.eof?
135
148
  elsif wire_type == ::Protobuf::WireType::FIXED32
136
- array << stream.read(4) until stream.eof?
149
+ array << decode(stream.read(4)) until stream.eof?
137
150
  end
138
151
  end
139
152
 
140
- def setter
141
- @setter ||= "#{name}="
142
- end
143
-
144
153
  def tag_encoded
145
154
  @tag_encoded ||= begin
146
155
  case
@@ -205,7 +214,6 @@ module Protobuf
205
214
  fail "Can't use packed encoding for '#{type_class}' type"
206
215
  end
207
216
  end
208
-
209
217
  end
210
218
  end
211
219
  end
@@ -3,7 +3,9 @@ require 'protobuf/field/varint_field'
3
3
  module Protobuf
4
4
  module Field
5
5
  class BoolField < VarintField
6
+ FALSE_ENCODE = [0].pack('C')
6
7
  FALSE_STRING = "false".freeze
8
+ TRUE_ENCODE = [1].pack('C')
7
9
  TRUE_STRING = "true".freeze
8
10
 
9
11
  ##
@@ -19,16 +21,16 @@ module Protobuf
19
21
  # #
20
22
 
21
23
  def acceptable?(val)
22
- [true, false].include?(val) || %w(true false).include?(val)
24
+ val == true || val == false || val == TRUE_STRING || val == FALSE_STRING
23
25
  end
24
26
 
25
27
  def coerce!(val)
26
- case val
27
- when String
28
- val == TRUE_STRING
29
- else
30
- val
31
- end
28
+ return true if val == true
29
+ return false if val == false
30
+ return true if val == TRUE_STRING
31
+ return false if val == FALSE_STRING
32
+
33
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
32
34
  end
33
35
 
34
36
  def decode(value)
@@ -36,7 +38,7 @@ module Protobuf
36
38
  end
37
39
 
38
40
  def encode(value)
39
- [value ? 1 : 0].pack('C')
41
+ value ? TRUE_ENCODE : FALSE_ENCODE
40
42
  end
41
43
 
42
44
  private
@@ -33,11 +33,12 @@ module Protobuf
33
33
  end
34
34
 
35
35
  def encode(value)
36
- if value.is_a?(::Protobuf::Message)
37
- value_to_encode = value.encode
38
- else
39
- value_to_encode = value.dup
40
- end
36
+ value_to_encode =
37
+ if value.is_a?(::Protobuf::Message)
38
+ value.encode
39
+ else
40
+ value.dup
41
+ end
41
42
 
42
43
  value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
43
44
  string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
@@ -45,6 +46,13 @@ module Protobuf
45
46
  "#{string_size}#{value_to_encode}"
46
47
  end
47
48
 
49
+ def encode_to_stream(value, stream)
50
+ value = value.encode if value.is_a?(::Protobuf::Message)
51
+ byte_size = ::Protobuf::Field::VarintField.encode(value.bytesize)
52
+
53
+ stream << tag_encoded << byte_size << value
54
+ end
55
+
48
56
  def wire_type
49
57
  ::Protobuf::WireType::LENGTH_DELIMITED
50
58
  end
@@ -52,7 +60,7 @@ module Protobuf
52
60
  def coerce!(value)
53
61
  case value
54
62
  when String, Symbol
55
- "#{value}"
63
+ value.to_s
56
64
  when NilClass
57
65
  nil
58
66
  when ::Protobuf::Message
@@ -22,6 +22,8 @@ module Protobuf
22
22
 
23
23
  def coerce!(val)
24
24
  Float(val)
25
+ rescue ArgumentError
26
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
25
27
  end
26
28
 
27
29
  def decode(bytes)
@@ -28,6 +28,16 @@ module Protobuf
28
28
  "#{::Protobuf::Field::VarintField.encode(value_to_encode.size)}#{value_to_encode}"
29
29
  end
30
30
 
31
+ def encode_to_stream(value, stream)
32
+ if value.encoding != ::Protobuf::Field::StringField::ENCODING
33
+ value = value.dup
34
+ value.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
35
+ end
36
+
37
+ byte_size = ::Protobuf::Field::VarintField.encode(value.bytesize)
38
+ stream << tag_encoded << byte_size << value
39
+ end
40
+
31
41
  end
32
42
  end
33
43
  end
@@ -50,17 +50,27 @@ module Protobuf
50
50
  ##
51
51
  # Public Instance Methods
52
52
  #
53
-
54
53
  def acceptable?(val)
55
- int_val = coerce!(val)
54
+ int_val = if val.is_a?(Integer)
55
+ return true if val >= 0 && val < INT32_MAX # return quickly for smallest integer size, hot code path
56
+ val
57
+ elsif val.is_a?(Numeric)
58
+ val.to_i
59
+ else
60
+ Integer(val, 10)
61
+ end
62
+
56
63
  int_val >= self.class.min && int_val <= self.class.max
57
64
  rescue
58
65
  false
59
66
  end
60
67
 
61
68
  def coerce!(val)
69
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'" unless acceptable?(val)
62
70
  return val.to_i if val.is_a?(Numeric)
63
71
  Integer(val, 10)
72
+ rescue ArgumentError
73
+ fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
64
74
  end
65
75
 
66
76
  def decode(value)