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,55 @@
1
+ module Protobuf
2
+ module Descriptor
3
+ class Descriptor
4
+ def initialize(message_class)
5
+ @message_class = message_class
6
+ end
7
+
8
+ def proto_type
9
+ 'Google::Protobuf::DescriptorProto'
10
+ end
11
+
12
+ def build(proto, opt={})
13
+ mod = opt[:module]
14
+ cls = mod.const_set(proto.name, Class.new(@message_class))
15
+ proto.nested_type.each do |message_proto|
16
+ Protobuf::Message.descriptor.build(message_proto, :module => cls)
17
+ end
18
+ proto.enum_type.each do |enum_proto|
19
+ Protobuf::Enum.descriptor.build(enum_proto, :module => cls)
20
+ end
21
+ proto.field.each do |field_proto|
22
+ Protobuf::Field::BaseField.descriptor.build(field_proto, :class => cls)
23
+ end
24
+ end
25
+
26
+ def unbuild(parent_proto)
27
+ message_proto = Google::Protobuf::DescriptorProto.new
28
+ message_proto.name = @message_class.to_s.split('::').last
29
+ @message_class.fields.each do |tag, field|
30
+ field.descriptor.unbuild(message_proto)
31
+ end
32
+ ObjectSpace.each_object(Class) do |cls|
33
+ if innerclass?(@message_class, cls)
34
+ cls.descriptor.unbuild(message_proto)
35
+ end
36
+ end
37
+
38
+ case parent_proto
39
+ when Google::Protobuf::FileDescriptorProto
40
+ parent_proto.message_type << message_proto
41
+ when Google::Protobuf::DescriptorProto
42
+ parent_proto.nested_type << message_proto
43
+ else
44
+ raise TypeError, parent_proto.class.name
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def innerclass?(parent, child)
51
+ child.name =~ /::/ && child.name.split('::')[0..-2].join('::') == parent.name
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,143 @@
1
+ require 'protobuf/descriptor/file_descriptor'
2
+
3
+ module Protobuf
4
+ module Descriptor
5
+ def self.id2type(type_id)
6
+ require 'protobuf/descriptor/descriptor_proto'
7
+ case type_id
8
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE
9
+ :double
10
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FLOAT
11
+ :float
12
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
13
+ :int64
14
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64
15
+ :unit64
16
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
17
+ :int64
18
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64
19
+ :fixed64
20
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32
21
+ :fixed32
22
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL
23
+ :bool
24
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
25
+ :string
26
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP
27
+ :group
28
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
29
+ :message
30
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BYTES
31
+ :bytes
32
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32
33
+ :uint32
34
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM
35
+ :enum
36
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32
37
+ :sfixed32
38
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64
39
+ :sfixed64
40
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32
41
+ :sint32
42
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64
43
+ :sint64
44
+ else
45
+ raise ArgumentError, "Invalid type: #{proto.type}"
46
+ end
47
+ end
48
+
49
+ def self.type2id(type)
50
+ require 'protobuf/descriptor/descriptor_proto'
51
+ case type
52
+ when :double
53
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_DOUBLE
54
+ when :float
55
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_FLOAT
56
+ when :int64
57
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT64
58
+ when :unit64
59
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT64
60
+ when :int64
61
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_INT32
62
+ when :fixed64
63
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED64
64
+ when :fixed32
65
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_FIXED32
66
+ when Google::Protobuf::FieldDescriptorProto::Type::TYPE_BOOL
67
+ :bool
68
+ when :string
69
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
70
+ when :group
71
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_GROUP
72
+ when :message
73
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
74
+ when :bytes
75
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_BYTES
76
+ when :uint32
77
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_UINT32
78
+ when :enum
79
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM
80
+ when :sfixed32
81
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED32
82
+ when :sfixed64
83
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_SFIXED64
84
+ when :sint32
85
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT32
86
+ when :sint64
87
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_SINT64
88
+ else
89
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE
90
+ end
91
+ end
92
+
93
+ def self.id2label(label_id)
94
+ require 'protobuf/descriptor/descriptor_proto'
95
+ case label_id
96
+ when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED
97
+ :required
98
+ when Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL
99
+ :optional
100
+ when Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
101
+ :repeated
102
+ else
103
+ raise ArgumentError, "Invalid label: #{proto.label}"
104
+ end
105
+ end
106
+
107
+ def self.label2id(label)
108
+ require 'protobuf/descriptor/descriptor_proto'
109
+ case label
110
+ when :required
111
+ Google::Protobuf::FieldDescriptorProto::Label::LABEL_REQUIRED
112
+ when :optional
113
+ Google::Protobuf::FieldDescriptorProto::Label::LABEL_OPTIONAL
114
+ when :repeated
115
+ Google::Protobuf::FieldDescriptorProto::Label::LABEL_REPEATED
116
+ else
117
+ raise ArgumentError, "Invalid label: #{label}"
118
+ end
119
+ end
120
+
121
+ class DescriptorBuilder
122
+ class <<self
123
+
124
+ def proto_type
125
+ nil
126
+ end
127
+
128
+ def build(proto, opt={})
129
+ acceptable_descriptor(proto).build(proto)
130
+ end
131
+
132
+ def acceptable_descriptor(proto)
133
+ Protobuf::Descriptor.constants.each do |class_name|
134
+ descriptor_class = Protobuf::Descriptor.const_get(class_name)
135
+ if descriptor_class.respond_to?(:proto_type) && descriptor_class.proto_type == proto.class.name
136
+ return descriptor_class
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,138 @@
1
+ require 'protobuf/message/message'
2
+ require 'protobuf/message/enum'
3
+ require 'protobuf/message/extend'
4
+
5
+ module Google
6
+ module Protobuf
7
+ ::Protobuf::OPTIONS[:"java_package"] = "com.google.protobuf"
8
+ ::Protobuf::OPTIONS[:"java_outer_classname"] = "DescriptorProtos"
9
+ ::Protobuf::OPTIONS[:"optimize_for"] = :SPEED
10
+ class FileDescriptorProto < ::Protobuf::Message
11
+ defined_in __FILE__
12
+ optional :string, :name, 1
13
+ optional :string, :package, 2
14
+ repeated :string, :dependency, 3
15
+ repeated :DescriptorProto, :message_type, 4
16
+ repeated :EnumDescriptorProto, :enum_type, 5
17
+ repeated :ServiceDescriptorProto, :service, 6
18
+ repeated :FieldDescriptorProto, :extension, 7
19
+ optional :FileOptions, :options, 8
20
+ end
21
+ class DescriptorProto < ::Protobuf::Message
22
+ defined_in __FILE__
23
+ optional :string, :name, 1
24
+ repeated :FieldDescriptorProto, :field, 2
25
+ repeated :FieldDescriptorProto, :extension, 6
26
+ repeated :DescriptorProto, :nested_type, 3
27
+ repeated :EnumDescriptorProto, :enum_type, 4
28
+ class ExtensionRange < ::Protobuf::Message
29
+ defined_in __FILE__
30
+ optional :int32, :start, 1
31
+ optional :int32, :end, 2
32
+ end
33
+ repeated :ExtensionRange, :extension_range, 5
34
+ optional :MessageOptions, :options, 7
35
+ end
36
+ class FieldDescriptorProto < ::Protobuf::Message
37
+ defined_in __FILE__
38
+ class Type < ::Protobuf::Enum
39
+ defined_in __FILE__
40
+ define :TYPE_DOUBLE, 1
41
+ define :TYPE_FLOAT, 2
42
+ define :TYPE_INT64, 3
43
+ define :TYPE_UINT64, 4
44
+ define :TYPE_INT32, 5
45
+ define :TYPE_FIXED64, 6
46
+ define :TYPE_FIXED32, 7
47
+ define :TYPE_BOOL, 8
48
+ define :TYPE_STRING, 9
49
+ define :TYPE_GROUP, 10
50
+ define :TYPE_MESSAGE, 11
51
+ define :TYPE_BYTES, 12
52
+ define :TYPE_UINT32, 13
53
+ define :TYPE_ENUM, 14
54
+ define :TYPE_SFIXED32, 15
55
+ define :TYPE_SFIXED64, 16
56
+ define :TYPE_SINT32, 17
57
+ define :TYPE_SINT64, 18
58
+ end
59
+ class Label < ::Protobuf::Enum
60
+ defined_in __FILE__
61
+ define :LABEL_OPTIONAL, 1
62
+ define :LABEL_REQUIRED, 2
63
+ define :LABEL_REPEATED, 3
64
+ end
65
+ optional :string, :name, 1
66
+ optional :int32, :number, 3
67
+ optional :Label, :label, 4
68
+ optional :Type, :type, 5
69
+ optional :string, :type_name, 6
70
+ optional :string, :extendee, 2
71
+ optional :string, :default_value, 7
72
+ optional :FieldOptions, :options, 8
73
+ end
74
+ class EnumDescriptorProto < ::Protobuf::Message
75
+ defined_in __FILE__
76
+ optional :string, :name, 1
77
+ repeated :EnumValueDescriptorProto, :value, 2
78
+ optional :EnumOptions, :options, 3
79
+ end
80
+ class EnumValueDescriptorProto < ::Protobuf::Message
81
+ defined_in __FILE__
82
+ optional :string, :name, 1
83
+ optional :int32, :number, 2
84
+ optional :EnumValueOptions, :options, 3
85
+ end
86
+ class ServiceDescriptorProto < ::Protobuf::Message
87
+ defined_in __FILE__
88
+ optional :string, :name, 1
89
+ repeated :MethodDescriptorProto, :method, 2
90
+ optional :ServiceOptions, :options, 3
91
+ end
92
+ class MethodDescriptorProto < ::Protobuf::Message
93
+ defined_in __FILE__
94
+ optional :string, :name, 1
95
+ optional :string, :input_type, 2
96
+ optional :string, :output_type, 3
97
+ optional :MethodOptions, :options, 4
98
+ end
99
+ class FileOptions < ::Protobuf::Message
100
+ defined_in __FILE__
101
+ optional :string, :java_package, 1
102
+ optional :string, :java_outer_classname, 8
103
+ optional :bool, :java_multiple_files, 10, :default => false
104
+ class OptimizeMode < ::Protobuf::Enum
105
+ defined_in __FILE__
106
+ define :SPEED, 1
107
+ define :CODE_SIZE, 2
108
+ end
109
+ optional :OptimizeMode, :optimize_for, 9, :default => :CODE_SIZE
110
+ end
111
+ class MessageOptions < ::Protobuf::Message
112
+ defined_in __FILE__
113
+ optional :bool, :message_set_wire_format, 1, :default => false
114
+ end
115
+ class FieldOptions < ::Protobuf::Message
116
+ defined_in __FILE__
117
+ optional :CType, :ctype, 1
118
+ class CType < ::Protobuf::Enum
119
+ defined_in __FILE__
120
+ define :CORD, 1
121
+ define :STRING_PIECE, 2
122
+ end
123
+ optional :string, :experimental_map_key, 9
124
+ end
125
+ class EnumOptions < ::Protobuf::Message
126
+ defined_in __FILE__
127
+ end
128
+ class EnumValueOptions < ::Protobuf::Message
129
+ defined_in __FILE__
130
+ end
131
+ class ServiceOptions < ::Protobuf::Message
132
+ defined_in __FILE__
133
+ end
134
+ class MethodOptions < ::Protobuf::Message
135
+ defined_in __FILE__
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,33 @@
1
+ module Protobuf
2
+ module Descriptor
3
+ class EnumDescriptor
4
+ def initialize(enum_class)
5
+ @enum_class = enum_class
6
+ end
7
+
8
+ def proto_type
9
+ Google::Protobuf::EnumDescriptorProto
10
+ end
11
+
12
+ def build(proto, opt)
13
+ mod = opt[:module]
14
+ cls = mod.const_set(proto.name, Class.new(Protobuf::Enum))
15
+ proto.value.each do |value_proto|
16
+ cls.class_eval { define value_proto.name, value_proto.number }
17
+ end
18
+ end
19
+
20
+ def unbuild(parent_proto)
21
+ enum_proto = Google::Protobuf::EnumDescriptorProto.new
22
+ enum_proto.name = @enum_class.name.split('::').last
23
+ @enum_class.values.each do |name, value|
24
+ enum_value_proto = Google::Protobuf::EnumValueDescriptorProto.new
25
+ enum_value_proto.name = name.to_s
26
+ enum_value_proto.number = value.value
27
+ enum_proto.value << enum_value_proto
28
+ end
29
+ parent_proto.enum_type << enum_proto
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ module Protobuf
2
+ module Descriptor
3
+ class FieldDescriptor
4
+ def initialize(field_instance=nil)
5
+ @field_instance = field_instance
6
+ end
7
+
8
+ def proto_type
9
+ 'Google::Protobuf::FieldDescriptorProto'
10
+ end
11
+
12
+ def build(proto, opt={})
13
+ cls = opt[:class]
14
+ rule = Protobuf::Descriptor.id2label(proto.label)
15
+ type = Protobuf::Descriptor.id2type(proto.type)
16
+ type = proto.type_name.to_sym if [:message, :enum].include?(type)
17
+ opts = {}
18
+ opts[:default] = proto.default_value if proto.default_value
19
+ cls.define_field(rule, type, proto.name, proto.number, opts)
20
+ end
21
+
22
+ def unbuild(parent_proto, extension=false)
23
+ field_proto = Google::Protobuf::FieldDescriptorProto.new
24
+ field_proto.name = @field_instance.name.to_s
25
+ field_proto.number = @field_instance.tag
26
+ field_proto.label = Protobuf::Descriptor.label2id(@field_instance.rule)
27
+ field_proto.type = Protobuf::Descriptor.type2id(@field_instance.type)
28
+ if [Google::Protobuf::FieldDescriptorProto::Type::TYPE_MESSAGE,
29
+ Google::Protobuf::FieldDescriptorProto::Type::TYPE_ENUM].include? field_proto.type
30
+ field_proto.type_name = @field_instance.type.to_s.split('::').last
31
+ end
32
+ field_proto.default_value = @field_instance.default.to_s if @field_instance.default
33
+
34
+ case parent_proto
35
+ when Google::Protobuf::FileDescriptorProto
36
+ parent_proto.extension << field_proto
37
+ when Google::Protobuf::DescriptorProto
38
+ if extension
39
+ parent_proto.extension << field_proto
40
+ else
41
+ parent_proto.field << field_proto
42
+ end
43
+ else
44
+ raise TypeError, parent_proto.class.name
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ module Protobuf
2
+ module Descriptor
3
+ class FileDescriptor
4
+ class <<self
5
+ def proto_type
6
+ 'Google::Protobuf::FileDescriptorProto'
7
+ end
8
+
9
+ def build(proto, opt={})
10
+ mod = Object
11
+ if package = proto.package and not package.empty?
12
+ module_names = package.split '::'
13
+ module_names.each do |module_name|
14
+ mod = mod.const_set module_name, Module.new
15
+ end
16
+ end
17
+ proto.message_type.each do |message_proto|
18
+ Protobuf::Message.descriptor.build message_proto, :module => mod
19
+ end
20
+ proto.enum_type.each do |enum_proto|
21
+ Protobuf::Enum.descriptor.build enum_proto, :module => mod
22
+ end
23
+ end
24
+
25
+ def unbuild(messages)
26
+ messages = [messages] unless messages.is_a? Array
27
+ proto = Google::Protobuf::FileDescriptorProto.new
28
+ proto.package = messages.first.to_s.split('::')[0..-2].join('::') if messages.first.to_s =~ /::/
29
+ messages.each do |message|
30
+ message.descriptor.unbuild proto
31
+ end
32
+ proto
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end