protobuf 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }