protobuf 1.0.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 (113) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +28 -0
  4. data/README.md +216 -0
  5. data/Rakefile +1 -0
  6. data/bin/rpc_server +117 -0
  7. data/bin/rprotoc +46 -0
  8. data/examples/addressbook.pb.rb +55 -0
  9. data/examples/addressbook.proto +24 -0
  10. data/examples/reading_a_message.rb +32 -0
  11. data/examples/writing_a_message.rb +46 -0
  12. data/lib/protobuf.rb +6 -0
  13. data/lib/protobuf/common/exceptions.rb +11 -0
  14. data/lib/protobuf/common/logger.rb +64 -0
  15. data/lib/protobuf/common/util.rb +59 -0
  16. data/lib/protobuf/common/wire_type.rb +10 -0
  17. data/lib/protobuf/compiler/compiler.rb +52 -0
  18. data/lib/protobuf/compiler/nodes.rb +323 -0
  19. data/lib/protobuf/compiler/proto.y +216 -0
  20. data/lib/protobuf/compiler/proto2.ebnf +79 -0
  21. data/lib/protobuf/compiler/proto_parser.rb +1425 -0
  22. data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
  23. data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
  24. data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
  25. data/lib/protobuf/compiler/template/rpc_service_implementation.erb +42 -0
  26. data/lib/protobuf/compiler/visitors.rb +302 -0
  27. data/lib/protobuf/descriptor/descriptor.proto +286 -0
  28. data/lib/protobuf/descriptor/descriptor.rb +55 -0
  29. data/lib/protobuf/descriptor/descriptor_builder.rb +143 -0
  30. data/lib/protobuf/descriptor/descriptor_proto.rb +138 -0
  31. data/lib/protobuf/descriptor/enum_descriptor.rb +33 -0
  32. data/lib/protobuf/descriptor/field_descriptor.rb +49 -0
  33. data/lib/protobuf/descriptor/file_descriptor.rb +37 -0
  34. data/lib/protobuf/message/decoder.rb +83 -0
  35. data/lib/protobuf/message/encoder.rb +46 -0
  36. data/lib/protobuf/message/enum.rb +62 -0
  37. data/lib/protobuf/message/extend.rb +8 -0
  38. data/lib/protobuf/message/field.rb +701 -0
  39. data/lib/protobuf/message/message.rb +402 -0
  40. data/lib/protobuf/message/protoable.rb +38 -0
  41. data/lib/protobuf/rpc/buffer.rb +74 -0
  42. data/lib/protobuf/rpc/client.rb +268 -0
  43. data/lib/protobuf/rpc/client_connection.rb +225 -0
  44. data/lib/protobuf/rpc/error.rb +34 -0
  45. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  46. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  47. data/lib/protobuf/rpc/rpc.pb.rb +107 -0
  48. data/lib/protobuf/rpc/server.rb +183 -0
  49. data/lib/protobuf/rpc/service.rb +244 -0
  50. data/lib/protobuf/rpc/stat.rb +70 -0
  51. data/lib/protobuf/version.rb +3 -0
  52. data/proto/rpc.proto +73 -0
  53. data/protobuf.gemspec +25 -0
  54. data/script/mk_parser +2 -0
  55. data/spec/functional/embedded_service_spec.rb +7 -0
  56. data/spec/proto/test.pb.rb +31 -0
  57. data/spec/proto/test.proto +31 -0
  58. data/spec/proto/test_service.rb +30 -0
  59. data/spec/proto/test_service_impl.rb +17 -0
  60. data/spec/spec_helper.rb +26 -0
  61. data/spec/unit/client_spec.rb +128 -0
  62. data/spec/unit/common/logger_spec.rb +121 -0
  63. data/spec/unit/enum_spec.rb +13 -0
  64. data/spec/unit/message_spec.rb +67 -0
  65. data/spec/unit/server_spec.rb +27 -0
  66. data/spec/unit/service_spec.rb +75 -0
  67. data/test/check_unbuild.rb +30 -0
  68. data/test/data/data.bin +3 -0
  69. data/test/data/data_source.py +14 -0
  70. data/test/data/types.bin +0 -0
  71. data/test/data/types_source.py +22 -0
  72. data/test/data/unk.png +0 -0
  73. data/test/proto/addressbook.pb.rb +66 -0
  74. data/test/proto/addressbook.proto +33 -0
  75. data/test/proto/addressbook_base.pb.rb +58 -0
  76. data/test/proto/addressbook_base.proto +26 -0
  77. data/test/proto/addressbook_ext.pb.rb +20 -0
  78. data/test/proto/addressbook_ext.proto +6 -0
  79. data/test/proto/collision.pb.rb +17 -0
  80. data/test/proto/collision.proto +5 -0
  81. data/test/proto/ext_collision.pb.rb +24 -0
  82. data/test/proto/ext_collision.proto +8 -0
  83. data/test/proto/ext_range.pb.rb +22 -0
  84. data/test/proto/ext_range.proto +7 -0
  85. data/test/proto/float_default.proto +10 -0
  86. data/test/proto/lowercase.pb.rb +30 -0
  87. data/test/proto/lowercase.proto +9 -0
  88. data/test/proto/merge.pb.rb +39 -0
  89. data/test/proto/merge.proto +15 -0
  90. data/test/proto/nested.pb.rb +30 -0
  91. data/test/proto/nested.proto +9 -0
  92. data/test/proto/optional_field.pb.rb +35 -0
  93. data/test/proto/optional_field.proto +12 -0
  94. data/test/proto/packed.pb.rb +22 -0
  95. data/test/proto/packed.proto +6 -0
  96. data/test/proto/rpc.proto +6 -0
  97. data/test/proto/types.pb.rb +84 -0
  98. data/test/proto/types.proto +37 -0
  99. data/test/test_addressbook.rb +56 -0
  100. data/test/test_compiler.rb +325 -0
  101. data/test/test_descriptor.rb +122 -0
  102. data/test/test_enum_value.rb +41 -0
  103. data/test/test_extension.rb +36 -0
  104. data/test/test_lowercase.rb +11 -0
  105. data/test/test_message.rb +128 -0
  106. data/test/test_optional_field.rb +103 -0
  107. data/test/test_packed_field.rb +40 -0
  108. data/test/test_parse.rb +15 -0
  109. data/test/test_repeated_types.rb +132 -0
  110. data/test/test_serialize.rb +61 -0
  111. data/test/test_standard_message.rb +96 -0
  112. data/test/test_types.rb +226 -0
  113. metadata +261 -0
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require '<%= underscored_name %>'
3
+
4
+ <%= module_name %>::<%= service_name %>.new(:Port => <%= default_port %>).start
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require 'protobuf/rpc/client'
3
+ require '<%= required_file %>'
4
+
5
+ # build request
6
+ request = <%= message_module %>::<%= request %>.new
7
+ # TODO: setup a request
8
+ raise StandardError, 'setup a request'
9
+
10
+ # create blunk response
11
+ response = <%= message_module %>::<%= response %>.new
12
+
13
+ # execute rpc
14
+ Protobuf::Rpc::Client.new('localhost', <%= default_port %>).call :<%= underscore name %>, request, response
15
+
16
+ # show response
17
+ puts response
18
+
@@ -0,0 +1,25 @@
1
+ require 'protobuf/rpc/server'
2
+ require 'protobuf/rpc/handler'
3
+ require '<%= required_file %>'
4
+
5
+ <%- rpcs.each do |name, request, response| -%>
6
+ class <%= module_name %>::<%= name %>Handler < Protobuf::Rpc::Handler
7
+ request <%= module_name %>::<%= request %>
8
+ response <%= module_name %>::<%= response %>
9
+
10
+ def self.process_request(request, response)
11
+ # TODO: edit this method
12
+ end
13
+ end
14
+
15
+ <%- end -%>
16
+ class <%= module_name %>::<%= service_name %> < Protobuf::Rpc::Server
17
+ def setup_handlers
18
+ @handlers = {
19
+ <%- rpcs.each do |name, | -%>
20
+ :<%= underscore name %> => <%= module_name %>::<%= name %>Handler,
21
+ <%- end -%>
22
+ }
23
+ end
24
+ end
25
+
@@ -0,0 +1,42 @@
1
+ <%-
2
+ module_array = module_name.split('::')
3
+ class_indent = ' '*(module_array.size)
4
+ -%>
5
+ require 'protobuf/rpc/service'
6
+ require '<%= required_file %>'
7
+
8
+ ## !! DO NOT EDIT THIS FILE !!
9
+ ##
10
+ ## To implement this service as defined by the protobuf, simply
11
+ ## reopen <%= module_name %>::<%= service_name %> and implement each service method:
12
+ ##
13
+ <%- module_array.each_with_index do |m, i| -%>
14
+ ## <%= "#{"\t"*i}module #{m}" %>
15
+ <%- end -%>
16
+ ## <%= class_indent %>class <%= service_name %>
17
+ ## <%= class_indent %>
18
+ <%- rpcs.each do |name, request, response| -%>
19
+ ## <%= class_indent %> # request -> <%= module_name %>::<%= request %>
20
+ ## <%= class_indent %> # response -> <%= module_name %>::<%= response %>
21
+ ## <%= class_indent %> def <%= underscore name %>
22
+ ## <%= class_indent %> # TODO: implement <%= underscore name %>
23
+ ## <%= class_indent %> end
24
+ ## <%= class_indent %>
25
+ <%- end -%>
26
+ ## <%= class_indent %>end
27
+ <%- (module_array.size-1).downto(0) do |i| -%>
28
+ ## <%= "#{"\t"*i}end" %>
29
+ <%- end -%>
30
+ ##
31
+
32
+ <%- module_array.each_with_index do |m, i| -%>
33
+ <%= "#{"\t"*i}module #{m}" %>
34
+ <%- end -%>
35
+ <%= class_indent %>class <%= service_name %> < Protobuf::Rpc::Service
36
+ <%- rpcs.each do |name, request, response| -%>
37
+ <%= class_indent %> rpc :<%= underscore name %>, <%= request %>, <%= response %>
38
+ <%- end -%>
39
+ <%= class_indent %>end
40
+ <%- (module_array.size-1).downto(0) do |i| -%>
41
+ <%= "#{"\t"*i}end" %>
42
+ <%- end -%>
@@ -0,0 +1,302 @@
1
+ require 'erb'
2
+ require 'fileutils'
3
+ require 'protobuf/descriptor/descriptor_proto'
4
+
5
+ module Protobuf
6
+ module Visitor
7
+ class Base
8
+ attr_reader :silent
9
+
10
+ def create_file_with_backup(filename, contents, executable=false)
11
+ if File.exist?(filename)
12
+ if File.read(filename) == contents
13
+ # do nothing
14
+ return
15
+ else
16
+ backup_filename = "#{filename}.#{Time.now.to_i}"
17
+ log_writing("#{backup_filename}", "backingup...")
18
+ FileUtils.copy(filename, backup_filename)
19
+ end
20
+ end
21
+
22
+ FileUtils.mkpath(File.dirname(filename))
23
+ File.open(filename, 'w') do |file|
24
+ log_writing(filename)
25
+ file.write(contents)
26
+ end
27
+ FileUtils.chmod(0755, filename) if executable
28
+ end
29
+
30
+ def log_writing(filename, message="wrote")
31
+ puts "#{message} #{filename}" unless silent
32
+ end
33
+ end
34
+
35
+ class CreateMessageVisitor < Base
36
+ attr_accessor :package, :indent, :context, :attach_proto, :proto_file
37
+
38
+ def initialize(proto_file=nil, proto_dir='.', out_dir='.')
39
+ @proto_dir, @out_dir = proto_dir, out_dir
40
+ @indent = 0
41
+ @context = []
42
+ @attach_proto = false
43
+ @proto_file = proto_file
44
+ end
45
+
46
+ def attach_proto?
47
+ @attach_proto
48
+ end
49
+
50
+ def commented_proto_contents
51
+ if proto_file
52
+ proto_filepath = if File.exist?(proto_file)
53
+ then proto_file
54
+ else "#{@proto_dir}/#{proto_file}"
55
+ end
56
+ File.read(proto_filepath).gsub(/^/, '# ')
57
+ end
58
+ end
59
+
60
+ def write(str)
61
+ ruby << "#{' ' * @indent}#{str}"
62
+ end
63
+
64
+ def increment
65
+ @indent += 1
66
+ end
67
+
68
+ def decrement
69
+ @indent -= 1
70
+ end
71
+
72
+ def close_ruby
73
+ while 0 < indent
74
+ decrement
75
+ write('end')
76
+ end
77
+ end
78
+
79
+ def ruby
80
+ @ruby ||= []
81
+ end
82
+
83
+ def to_s
84
+ @ruby.join("\n")
85
+ end
86
+
87
+ def in_context(klass, &block)
88
+ increment
89
+ context.push klass
90
+ block.call
91
+ context.pop
92
+ decrement
93
+ end
94
+
95
+ def visit(node)
96
+ node.accept_message_visitor(self)
97
+ self
98
+ end
99
+
100
+ def required_message_from_proto(proto_file)
101
+ rb_path = [
102
+ proto_file.sub(/\.proto\z/, '.pb.rb')
103
+ ].join('/').gsub(/\/{2,}/, '/')
104
+
105
+ unless File.exist?(rb_path)
106
+ Compiler.compile(proto_file, @proto_dir, @out_dir)
107
+ end
108
+
109
+ rb_path.sub(/\.rb$/, '')
110
+ end
111
+
112
+ def create_files(filename, out_dir, file_create)
113
+ begin
114
+ $: << File.expand_path(out_dir)
115
+ Class.new.class_eval(to_s) # check the message
116
+ $:.delete File.expand_path(out_dir)
117
+ rescue LoadError
118
+ puts "Error creating file #{filename}"
119
+ puts $!.message
120
+ exit 1
121
+ end
122
+
123
+ file = File.basename(filename)
124
+ message_module = Util.module_to_path(package.map{|p| p.to_s.capitalize}.join('::'))
125
+ filename = "#{out_dir}/#{message_module}/#{file}"
126
+
127
+ if file_create
128
+ log_writing(filename)
129
+ FileUtils.mkpath(File.dirname(filename))
130
+ File.open(filename, 'w') {|file| file.write(to_s) }
131
+ else
132
+ to_s
133
+ end
134
+ end
135
+ end
136
+
137
+ class CreateRpcVisitor < Base
138
+ attr_accessor :package, :services, :current_service, :file_contents
139
+
140
+ def initialize
141
+ @services = {}
142
+ @create_file = true
143
+ @file_contents = {}
144
+ end
145
+
146
+ def visit(node)
147
+ node.accept_rpc_visitor(self)
148
+ self
149
+ end
150
+
151
+ def add_rpc(name, request, response)
152
+ (@services[@current_service] ||= []) << [name, Util.moduleize(request), Util.moduleize(response)]
153
+ end
154
+
155
+ def create_files(message_file, out_dir, create_file=true)
156
+ @create_file = create_file
157
+ default_port = 9999
158
+ @services.each do |service_name, rpcs|
159
+ underscored_name = underscore service_name.to_s
160
+ message_module = package.map{|p| p.to_s.capitalize}.join('::')
161
+ required_file = [
162
+ Util.module_to_path(message_module),
163
+ File.basename(message_file.sub(/^\.\//, '').sub(/\.rb$/, ''))
164
+ ].join('/').gsub(/\/{2,}/, '/')
165
+
166
+ create_service(message_file, out_dir, underscored_name, message_module, service_name, default_port, rpcs, required_file)
167
+ end
168
+ @file_contents
169
+ end
170
+
171
+ def create_bin(out_dir, underscored_name, module_name, service_name, default_port)
172
+ bin_filename = "#{out_dir}/bin/start_#{underscored_name}"
173
+ bin_contents = template_erb('rpc_bin').result(binding)
174
+ create_file_with_backup(bin_filename, bin_contents, true) if @create_file
175
+ @file_contents[bin_filename] = bin_contents
176
+ end
177
+
178
+ def create_service(message_file, out_dir, underscored_name, module_name, service_name, default_port, rpcs, required_file)
179
+ service_filename = "#{out_dir}/#{Util.module_to_path(module_name)}/#{underscored_name}.rb"
180
+ service_contents = template_erb('rpc_service_implementation').result(binding)
181
+ create_file_with_backup(service_filename, service_contents) if @create_file
182
+ @file_contents[service_filename] = service_contents
183
+ end
184
+
185
+ def create_client(out_dir, underscored_name, default_port, name, request, response, message_module, required_file)
186
+ client_filename = "#{out_dir}/clients/#{Util.module_to_path(message_module)}_client_#{underscore name}.rb"
187
+ client_contents = template_erb('rpc_client').result binding
188
+ create_file_with_backup(client_filename, client_contents, true) if @create_file
189
+ @file_contents[client_filename] = client_contents
190
+ end
191
+
192
+ private
193
+
194
+ def underscore(str)
195
+ str.to_s.gsub(/\B[A-Z]/, '_\&').downcase
196
+ end
197
+
198
+ def template_erb(template)
199
+ ERB.new(File.read("#{File.dirname(__FILE__)}/template/#{template}.erb"), nil, '-')
200
+ end
201
+ end
202
+
203
+ class CreateDescriptorVisitor < Base
204
+ attr_reader :file_descriptor
205
+ attr_accessor :filename
206
+
207
+ def initialize(filename=nil)
208
+ @context = []
209
+ @filename = filename
210
+ end
211
+
212
+ def visit(node)
213
+ node.accept_descriptor_visitor(self)
214
+ self
215
+ end
216
+
217
+ def in_context(descriptor, &block)
218
+ @context.push descriptor
219
+ block.call
220
+ @context.pop
221
+ end
222
+
223
+ def current_descriptor
224
+ @context.last
225
+ end
226
+
227
+ def file_descriptor=(descriptor)
228
+ @file_descriptor = descriptor
229
+ @file_descriptor.name = @filename
230
+ end
231
+
232
+ def add_option(name, value)
233
+ options =
234
+ case current_descriptor
235
+ when Google::Protobuf::FileDescriptorProto
236
+ Google::Protobuf::FileOptions.new
237
+ when Google::Protobuf::DescriptorProto
238
+ Google::Protobuf::MessageOptions.new
239
+ when Google::Protobuf::FieldDescriptorProto
240
+ Google::Protobuf::FieldOptions.new
241
+ when Google::Protobuf::EnumDescriptorProto
242
+ Google::Protobuf::EnumOptions.new
243
+ when Google::Protobuf::EnumValueDescriptorProto
244
+ Google::Protobuf::EnumValueOptions.new
245
+ when Google::Protobuf::ServiceDescriptorProto
246
+ Google::Protobuf::ServiceOptions.new
247
+ when Google::Protobuf::MethodDescriptorProto
248
+ Google::Protobuf::MethodOptions.new
249
+ else
250
+ raise ArgumentError, 'Invalid context'
251
+ end
252
+ #TODO how should options be handled?
253
+ #current_descriptor.options << option
254
+ end
255
+
256
+ def descriptor=(descriptor)
257
+ case current_descriptor
258
+ when Google::Protobuf::FileDescriptorProto
259
+ current_descriptor.message_type << descriptor
260
+ when Google::Protobuf::DescriptorProto
261
+ current_descriptor.nested_type << descriptor
262
+ else
263
+ raise ArgumentError, 'Invalid context'
264
+ end
265
+ end
266
+ alias message_descriptor= descriptor=
267
+
268
+ def enum_descriptor=(descriptor)
269
+ current_descriptor.enum_type << descriptor
270
+ end
271
+
272
+ def enum_value_descriptor=(descriptor)
273
+ current_descriptor.value << descriptor
274
+ end
275
+
276
+ def service_descriptor=(descriptor)
277
+ current_descriptor.service << descriptor
278
+ end
279
+
280
+ def method_descriptor=(descriptor)
281
+ current_descriptor.method << descriptor
282
+ end
283
+
284
+ def field_descriptor=(descriptor)
285
+ case current_descriptor
286
+ when Google::Protobuf::FileDescriptorProto
287
+ current_descriptor.extension << descriptor
288
+ when Google::Protobuf::DescriptorProto
289
+ current_descriptor.field << descriptor
290
+ #TODO: how should i distiguish between field and extension
291
+ #current_descriptor.extension << descriptor
292
+ else
293
+ raise ArgumentError, 'Invalid context'
294
+ end
295
+ end
296
+
297
+ def extension_range_descriptor=(descriptor)
298
+ current_descriptor.extension_range << descriptor
299
+ end
300
+ end
301
+ end
302
+ end
@@ -0,0 +1,286 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2008 Google Inc.
3
+ // http://code.google.com/p/protobuf/
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+
17
+ // Author: kenton@google.com (Kenton Varda)
18
+ // Based on original Protocol Buffers design by
19
+ // Sanjay Ghemawat, Jeff Dean, and others.
20
+ //
21
+ // The messages in this file describe the definitions found in .proto files.
22
+ // A valid .proto file can be translated directly to a FileDescriptorProto
23
+ // without any other information (e.g. without reading its imports).
24
+
25
+
26
+
27
+ package google.protobuf;
28
+ option java_package = "com.google.protobuf";
29
+ option java_outer_classname = "DescriptorProtos";
30
+
31
+ // descriptor.proto must be optimized for speed because reflection-based
32
+ // algorithms don't work during bootstrapping.
33
+ option optimize_for = SPEED;
34
+
35
+ // Describes a complete .proto file.
36
+ message FileDescriptorProto {
37
+ optional string name = 1; // file name, relative to root of source tree
38
+ optional string package = 2; // e.g. "foo", "foo.bar", etc.
39
+
40
+ // Names of files imported by this file.
41
+ repeated string dependency = 3;
42
+
43
+ // All top-level definitions in this file.
44
+ repeated DescriptorProto message_type = 4;
45
+ repeated EnumDescriptorProto enum_type = 5;
46
+ repeated ServiceDescriptorProto service = 6;
47
+ repeated FieldDescriptorProto extension = 7;
48
+
49
+ optional FileOptions options = 8;
50
+ }
51
+
52
+ // Describes a message type.
53
+ message DescriptorProto {
54
+ optional string name = 1;
55
+
56
+ repeated FieldDescriptorProto field = 2;
57
+ repeated FieldDescriptorProto extension = 6;
58
+
59
+ repeated DescriptorProto nested_type = 3;
60
+ repeated EnumDescriptorProto enum_type = 4;
61
+
62
+ message ExtensionRange {
63
+ optional int32 start = 1;
64
+ optional int32 end = 2;
65
+ }
66
+ repeated ExtensionRange extension_range = 5;
67
+
68
+ optional MessageOptions options = 7;
69
+ }
70
+
71
+ // Describes a field within a message.
72
+ message FieldDescriptorProto {
73
+ enum Type {
74
+ // 0 is reserved for errors.
75
+ // Order is weird for historical reasons.
76
+ TYPE_DOUBLE = 1;
77
+ TYPE_FLOAT = 2;
78
+ TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers
79
+ // take 10 bytes. Use TYPE_SINT64 if negative
80
+ // values are likely.
81
+ TYPE_UINT64 = 4;
82
+ TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers
83
+ // take 10 bytes. Use TYPE_SINT32 if negative
84
+ // values are likely.
85
+ TYPE_FIXED64 = 6;
86
+ TYPE_FIXED32 = 7;
87
+ TYPE_BOOL = 8;
88
+ TYPE_STRING = 9;
89
+ TYPE_GROUP = 10; // Tag-delimited aggregate.
90
+ TYPE_MESSAGE = 11; // Length-delimited aggregate.
91
+
92
+ // New in version 2.
93
+ TYPE_BYTES = 12;
94
+ TYPE_UINT32 = 13;
95
+ TYPE_ENUM = 14;
96
+ TYPE_SFIXED32 = 15;
97
+ TYPE_SFIXED64 = 16;
98
+ TYPE_SINT32 = 17; // Uses ZigZag encoding.
99
+ TYPE_SINT64 = 18; // Uses ZigZag encoding.
100
+ };
101
+
102
+ enum Label {
103
+ // 0 is reserved for errors
104
+ LABEL_OPTIONAL = 1;
105
+ LABEL_REQUIRED = 2;
106
+ LABEL_REPEATED = 3;
107
+ // TODO(sanjay): Should we add LABEL_MAP?
108
+ };
109
+
110
+ optional string name = 1;
111
+ optional int32 number = 3;
112
+ optional Label label = 4;
113
+
114
+ // If type_name is set, this need not be set. If both this and type_name
115
+ // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
116
+ optional Type type = 5;
117
+
118
+ // For message and enum types, this is the name of the type. If the name
119
+ // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
120
+ // rules are used to find the type (i.e. first the nested types within this
121
+ // message are searched, then within the parent, on up to the root
122
+ // namespace).
123
+ optional string type_name = 6;
124
+
125
+ // For extensions, this is the name of the type being extended. It is
126
+ // resolved in the same manner as type_name.
127
+ optional string extendee = 2;
128
+
129
+ // For numeric types, contains the original text representation of the value.
130
+ // For booleans, "true" or "false".
131
+ // For strings, contains the default text contents (not escaped in any way).
132
+ // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
133
+ // TODO(kenton): Base-64 encode?
134
+ optional string default_value = 7;
135
+
136
+ optional FieldOptions options = 8;
137
+ }
138
+
139
+ // Describes an enum type.
140
+ message EnumDescriptorProto {
141
+ optional string name = 1;
142
+
143
+ repeated EnumValueDescriptorProto value = 2;
144
+
145
+ optional EnumOptions options = 3;
146
+ }
147
+
148
+ // Describes a value within an enum.
149
+ message EnumValueDescriptorProto {
150
+ optional string name = 1;
151
+ optional int32 number = 2;
152
+
153
+ optional EnumValueOptions options = 3;
154
+ }
155
+
156
+ // Describes a service.
157
+ message ServiceDescriptorProto {
158
+ optional string name = 1;
159
+ repeated MethodDescriptorProto method = 2;
160
+
161
+ optional ServiceOptions options = 3;
162
+ }
163
+
164
+ // Describes a method of a service.
165
+ message MethodDescriptorProto {
166
+ optional string name = 1;
167
+
168
+ // Input and output type names. These are resolved in the same way as
169
+ // FieldDescriptorProto.type_name, but must refer to a message type.
170
+ optional string input_type = 2;
171
+ optional string output_type = 3;
172
+
173
+ optional MethodOptions options = 4;
174
+ }
175
+
176
+ // ===================================================================
177
+ // Options
178
+
179
+ // Each of the definitions above may have "options" attached. These are
180
+ // just annotations which may cause code to be generated slightly differently
181
+ // or may contain hints for code that manipulates protocol messages.
182
+
183
+ // TODO(kenton): Allow extensions to options.
184
+
185
+ message FileOptions {
186
+
187
+ // Sets the Java package where classes generated from this .proto will be
188
+ // placed. By default, the proto package is used, but this is often
189
+ // inappropriate because proto packages do not normally start with backwards
190
+ // domain names.
191
+ optional string java_package = 1;
192
+
193
+
194
+ // If set, all the classes from the .proto file are wrapped in a single
195
+ // outer class with the given name. This applies to both Proto1
196
+ // (equivalent to the old "--one_java_file" option) and Proto2 (where
197
+ // a .proto always translates to a single class, but you may want to
198
+ // explicitly choose the class name).
199
+ optional string java_outer_classname = 8;
200
+
201
+ // If set true, then the Java code generator will generate a separate .java
202
+ // file for each top-level message, enum, and service defined in the .proto
203
+ // file. Thus, these types will *not* be nested inside the outer class
204
+ // named by java_outer_classname. However, the outer class will still be
205
+ // generated to contain the file's getDescriptor() method as well as any
206
+ // top-level extensions defined in the file.
207
+ optional bool java_multiple_files = 10 [default=false];
208
+
209
+ // Generated classes can be optimized for speed or code size.
210
+ enum OptimizeMode {
211
+ SPEED = 1; // Generate complete code for parsing, serialization, etc.
212
+ CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
213
+ }
214
+ optional OptimizeMode optimize_for = 9 [default=CODE_SIZE];
215
+ }
216
+
217
+ message MessageOptions {
218
+ // Set true to use the old proto1 MessageSet wire format for extensions.
219
+ // This is provided for backwards-compatibility with the MessageSet wire
220
+ // format. You should not use this for any other reason: It's less
221
+ // efficient, has fewer features, and is more complicated.
222
+ //
223
+ // The message must be defined exactly as follows:
224
+ // message Foo {
225
+ // option message_set_wire_format = true;
226
+ // extensions 4 to max;
227
+ // }
228
+ // Note that the message cannot have any defined fields; MessageSets only
229
+ // have extensions.
230
+ //
231
+ // All extensions of your type must be singular messages; e.g. they cannot
232
+ // be int32s, enums, or repeated messages.
233
+ //
234
+ // Because this is an option, the above two restrictions are not enforced by
235
+ // the protocol compiler.
236
+ optional bool message_set_wire_format = 1 [default=false];
237
+ }
238
+
239
+ message FieldOptions {
240
+ // The ctype option instructs the C++ code generator to use a different
241
+ // representation of the field than it normally would. See the specific
242
+ // options below. This option is not yet implemented in the open source
243
+ // release -- sorry, we'll try to include it in a future version!
244
+ optional CType ctype = 1;
245
+ enum CType {
246
+ CORD = 1;
247
+
248
+ STRING_PIECE = 2;
249
+ }
250
+
251
+ // EXPERIMENTAL. DO NOT USE.
252
+ // For "map" fields, the name of the field in the enclosed type that
253
+ // is the key for this map. For example, suppose we have:
254
+ // message Item {
255
+ // required string name = 1;
256
+ // required string value = 2;
257
+ // }
258
+ // message Config {
259
+ // repeated Item items = 1 [experimental_map_key="name"];
260
+ // }
261
+ // In this situation, the map key for Item will be set to "name".
262
+ // TODO: Fully-implement this, then remove the "experimental_" prefix.
263
+ optional string experimental_map_key = 9;
264
+ }
265
+
266
+ message EnumOptions {
267
+ }
268
+
269
+ message EnumValueOptions {
270
+ }
271
+
272
+ message ServiceOptions {
273
+
274
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
275
+ // framework. We apologize for hoarding these numbers to ourselves, but
276
+ // we were already using them long before we decided to release Protocol
277
+ // Buffers.
278
+ }
279
+
280
+ message MethodOptions {
281
+
282
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
283
+ // framework. We apologize for hoarding these numbers to ourselves, but
284
+ // we were already using them long before we decided to release Protocol
285
+ // Buffers.
286
+ }