protobuf_descriptor 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/.yardopts +1 -1
- data/ChangeLog.rdoc +12 -0
- data/README.md +61 -0
- data/Rakefile +114 -0
- data/lib/protobuf_descriptor/enum_descriptor.rb +17 -11
- data/lib/protobuf_descriptor/enum_value_descriptor.rb +29 -0
- data/lib/protobuf_descriptor/field_descriptor.rb +80 -0
- data/lib/protobuf_descriptor/file_descriptor.rb +37 -17
- data/lib/protobuf_descriptor/has_children.rb +49 -0
- data/lib/protobuf_descriptor/has_parent.rb +42 -0
- data/lib/protobuf_descriptor/message_descriptor.rb +20 -104
- data/lib/protobuf_descriptor/method_descriptor.rb +54 -0
- data/lib/protobuf_descriptor/named_child.rb +7 -0
- data/lib/protobuf_descriptor/service_descriptor.rb +9 -61
- data/lib/protobuf_descriptor/version.rb +1 -1
- data/lib/protobuf_descriptor.rb +20 -5
- data/protobuf_descriptor.gemspec +3 -2
- data/spec/field_descriptor_spec.rb +1 -1
- data/spec/file_descriptor_spec.rb +0 -1
- data/spec/method_descriptor_spec.rb +1 -1
- data/spec/protobuf_descriptor_spec.rb +3 -3
- data/spec/protoc_generator_spec.rb +6 -9
- data/spec/protos/custom_options/custom_options.proto +53 -0
- data/spec/protos/custom_options/google/protobuf/descriptor.proto +620 -0
- data/spec/protos/custom_options.desc +0 -0
- data/spec/protos/custom_options.java.zip +0 -0
- data/spec/protos/custom_options.wire.zip +0 -0
- data/spec/protos/generator_test.desc +24 -0
- data/spec/protos/generator_test.java.zip +0 -0
- data/spec/protos/generator_test.wire.zip +0 -0
- data/spec/protos/service_rpc_test.desc +71 -0
- data/spec/protos/service_rpc_test.java.zip +0 -0
- data/spec/protos/service_rpc_test.wire.zip +0 -0
- data/spec/protos/single_file_test.desc +0 -0
- data/spec/protos/single_file_test.java.zip +0 -0
- data/spec/protos/single_file_test.wire.zip +0 -0
- data/spec/protos/source_info/foo.proto +59 -0
- data/spec/protos/source_info.desc +22 -0
- data/spec/protos/source_info.java.zip +0 -0
- data/spec/protos/source_info.srcinfo.desc +0 -0
- data/spec/protos/source_info.wire.zip +0 -0
- data/spec/service_descriptor_spec.rb +1 -1
- data/spec/source_code_info_spec.rb +57 -0
- data/spec/spec_helper.rb +29 -57
- data/spec/wire_generator_spec.rb +6 -11
- metadata +69 -11
- data/Gemfile.lock +0 -58
- data/README.rdoc +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96fc09ef03f710c5955087be5c7296009c3e3122
|
4
|
+
data.tar.gz: 1be9567e58b0188dc5c9b6d84daf60168ca3d07c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0570eb154fab727bdcbe836ad82100ec194a730e0a906ff91178658c18bab228929816dc55ba41e9662e268f4305f8d4342c2fd8c9e5dfab5198ea64c9307974
|
7
|
+
data.tar.gz: efd4d050cd8b0298626ba3a5a882520b24c72f6b43b43adbb08ad015267b6aef10750b638c1e9ec59461b44dd0407879c9fbe89bfbb5dbd666696a2cdc85848d
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/.yardopts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--markup
|
1
|
+
--markup markdown --title "protobuf_descriptor Documentation" --protected
|
data/ChangeLog.rdoc
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 1.1.0 / 2014-05-14
|
2
|
+
|
3
|
+
Add support for accessing the +source_code_info+ bits of protobuf
|
4
|
+
descriptors. This mainly means that the leading and trailing comments can be
|
5
|
+
extracted for various declarations.
|
6
|
+
|
7
|
+
=== 1.0.1 / not released
|
8
|
+
|
9
|
+
Remove active_support dependency. The protobuf library still requires
|
10
|
+
active_support though, so this doesn't really change anything.
|
11
|
+
|
12
|
+
|
1
13
|
=== 1.0.0 / 2014-04-25
|
2
14
|
|
3
15
|
Huge version bump, update gem dependency to not be non-sensical. Should have no
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# protobuf_descriptor
|
2
|
+
|
3
|
+
[][gem]
|
4
|
+
[][travis]
|
5
|
+
[][license]
|
6
|
+
|
7
|
+
[gem]: https://rubygems.org/gems/protobuf_descriptor
|
8
|
+
[travis]: https://travis-ci.org/hfwang/protobuf_descriptor
|
9
|
+
[license]: https://github.com/hfwang/protobuf_descriptor/blob/master/LICENSE.txt
|
10
|
+
|
11
|
+
* [Homepage](https://rubygems.org/gems/protobuf_descriptor)
|
12
|
+
* [Documentation](http://rubydoc.info/github/hfwang/protobuf_descriptor/master/frames)
|
13
|
+
|
14
|
+
## Description
|
15
|
+
|
16
|
+
Protobuf_descriptor provides helper methods to make working with Google Protocol
|
17
|
+
Buffer descriptors easier, go figure.. It handles type resolution, and computing
|
18
|
+
type names (both within protocol buffers and in the generated output).
|
19
|
+
|
20
|
+
## Examples
|
21
|
+
|
22
|
+
Given the `descriptor.desc` generated by the protocol buffer compiler, you
|
23
|
+
can introspect the various data types. This example references the descriptor
|
24
|
+
that would be generated by compiling
|
25
|
+
[single_file.proto](https://github.com/hfwang/protobuf_descriptor/blob/master/spec/protos/single_file_test/single_file.proto)
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'protobuf_descriptor'
|
29
|
+
descriptor = ProtobufDescriptor.load("descriptor.desc")
|
30
|
+
|
31
|
+
# Load a single file by its filename/basename
|
32
|
+
file_descriptor = descriptor[:single_file]
|
33
|
+
|
34
|
+
# Grab a handle to an enum, or a message
|
35
|
+
file_descriptor.messages[:FieldOptions]
|
36
|
+
file_descriptor.enums[:UnnestedEnum]
|
37
|
+
|
38
|
+
# Also allows resolving types by their fully qualified name:
|
39
|
+
descriptor.resolve_type(".porkbuns.UnnestedEnum") # note the leading "."
|
40
|
+
# or even doing so relative to another enum
|
41
|
+
descriptor.resolve_type("CType", ".porkbuns.FieldOptions")
|
42
|
+
```
|
43
|
+
|
44
|
+
For even more gory details, please peruse the actual
|
45
|
+
[documentation](http://rubydoc.info/github/hfwang/protobuf_descriptor/master/frames).
|
46
|
+
|
47
|
+
## Requirements
|
48
|
+
|
49
|
+
I've only tested this on Ruby 1.9.3+. If it works for you on an older version of
|
50
|
+
Ruby, let me know. You most likely want to install the
|
51
|
+
[Google Protocol Buffer library](https://code.google.com/p/protobuf/).
|
52
|
+
|
53
|
+
## Install
|
54
|
+
|
55
|
+
$ gem install protobuf_descriptor
|
56
|
+
|
57
|
+
## Copyright
|
58
|
+
|
59
|
+
Copyright (c) 2014 Hsiu-Fan Wang
|
60
|
+
|
61
|
+
See LICENSE.txt for details.
|
data/Rakefile
CHANGED
@@ -41,6 +41,120 @@ task :spec => ["wire-compiler.jar"] do |t|
|
|
41
41
|
# Declare this to ensure wire-compiler is downloaded
|
42
42
|
end
|
43
43
|
|
44
|
+
desc "Compiles the protocol buffer decls used by the specs"
|
45
|
+
task :compile_spec_protos do
|
46
|
+
require "pathname"
|
47
|
+
require "tempfile"
|
48
|
+
require "tmpdir"
|
49
|
+
require "zip"
|
50
|
+
|
51
|
+
VERBOSE = ENV["VERBOSE"]
|
52
|
+
|
53
|
+
exec_proto_compiler = lambda do |args|
|
54
|
+
args = {
|
55
|
+
:source => ".",
|
56
|
+
:extra_args => [],
|
57
|
+
:plugin => nil,
|
58
|
+
:plugin_out => "",
|
59
|
+
:out => "out.desc",
|
60
|
+
:include_source_info => false,
|
61
|
+
}.merge(args)
|
62
|
+
args[:source] += '/' unless args[:source].end_with?('/')
|
63
|
+
|
64
|
+
command = []
|
65
|
+
command << "protoc"
|
66
|
+
command << "-I#{args[:source]}"
|
67
|
+
if args[:plugin]
|
68
|
+
command << "--#{args[:plugin]}_out=#{args[:plugin_out]}"
|
69
|
+
end
|
70
|
+
command += args[:extra_args]
|
71
|
+
command << "--descriptor_set_out=#{args[:out]}"
|
72
|
+
if args[:include_source_info]
|
73
|
+
command << "--include_source_info"
|
74
|
+
end
|
75
|
+
command += Dir.glob(File.join(args[:source], "**", "*.proto"))
|
76
|
+
|
77
|
+
rv = system(*command)
|
78
|
+
|
79
|
+
raise "ProtobufDescriptor generation failed!" unless rv
|
80
|
+
end
|
81
|
+
|
82
|
+
exec_wire_compiler = lambda do |args|
|
83
|
+
args = {
|
84
|
+
:out => ".",
|
85
|
+
:source => ".",
|
86
|
+
:extra_args => []
|
87
|
+
}.merge(args)
|
88
|
+
|
89
|
+
jar_path = File.realpath(File.join(File.dirname(__FILE__), "wire-compiler.jar"))
|
90
|
+
command = ["java", "-jar", jar_path]
|
91
|
+
command << "--proto_path=#{args[:source]}"
|
92
|
+
command += args[:extra_args]
|
93
|
+
command << "--java_out=#{args[:out]}"
|
94
|
+
sources = Dir.glob(File.join(args[:source], "**", "*.proto")).map { |p|
|
95
|
+
Pathname.new(p).relative_path_from(Pathname.new(args[:source])).to_s
|
96
|
+
}
|
97
|
+
command += sources
|
98
|
+
|
99
|
+
tmp_log = Tempfile.new(["wire-compiler", ".log"])
|
100
|
+
begin
|
101
|
+
rv = system(*command, out: [tmp_log.path, "a"], err: [tmp_log.path, "a"])
|
102
|
+
puts File.read(tmp_log) if VERBOSE
|
103
|
+
|
104
|
+
raise "Wire protobuf generation failed!\n#{File.read(tmp_log)}" unless rv
|
105
|
+
ensure
|
106
|
+
tmp_log.close
|
107
|
+
tmp_log.unlink
|
108
|
+
end
|
109
|
+
end
|
110
|
+
create_zip = lambda do |dir, dest|
|
111
|
+
dirpath = Pathname.new(dir)
|
112
|
+
File.delete(dest) if File.exist?(dest)
|
113
|
+
Zip::File.open(dest, Zip::File::CREATE) do |zipfile|
|
114
|
+
# require "pry"
|
115
|
+
# binding.pry
|
116
|
+
(Dir[File.join(dir, "**", "**")] + Dir[File.join(dir, "**")]).uniq.each do |file|
|
117
|
+
next if File.directory?(file)
|
118
|
+
relative_path = Pathname.new(file).relative_path_from(dirpath)
|
119
|
+
zipfile.add(relative_path, file)
|
120
|
+
puts "#{dest} <- #{relative_path}" if VERBOSE
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
file_sets = Dir["spec/protos/*"].select { |d| File.directory?(d) }
|
126
|
+
|
127
|
+
source = "spec/protos/source_info"
|
128
|
+
puts "Building #{source} (with included source info)"
|
129
|
+
exec_proto_compiler.call({
|
130
|
+
:out => "#{source}.srcinfo.desc",
|
131
|
+
:source => source,
|
132
|
+
:include_source_info => true
|
133
|
+
})
|
134
|
+
file_sets.each do |source|
|
135
|
+
puts "Building #{source}"
|
136
|
+
Dir.mktmpdir do |dir|
|
137
|
+
args = {
|
138
|
+
:out => "#{source}.desc",
|
139
|
+
:source => source,
|
140
|
+
:plugin => :java,
|
141
|
+
:plugin_out => dir
|
142
|
+
}
|
143
|
+
exec_proto_compiler.call(args)
|
144
|
+
create_zip.call(dir, "#{source}.java.zip")
|
145
|
+
end
|
146
|
+
|
147
|
+
Dir.mktmpdir do |dir|
|
148
|
+
args = {
|
149
|
+
:source => source,
|
150
|
+
:out => dir
|
151
|
+
}
|
152
|
+
exec_wire_compiler.call(args)
|
153
|
+
create_zip.call(dir, "#{source}.wire.zip")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
44
158
|
file "wire-compiler.jar" do |t|
|
45
159
|
sh 'wget --no-check-certificate --output-document="wire-compiler.jar" "http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.squareup.wire&a=wire-compiler&v=LATEST&c=jar-with-dependencies"'
|
46
160
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
require "active_support"
|
2
|
-
require "protobuf_descriptor/named_child"
|
3
|
-
require "active_support/core_ext/module/delegation"
|
4
|
-
|
5
1
|
class ProtobufDescriptor
|
6
2
|
# Describes an enum type.
|
7
3
|
#
|
8
|
-
# See {+EnumDescriptorProto+}[https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#
|
4
|
+
# See {+EnumDescriptorProto+}[https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#171]
|
9
5
|
class EnumDescriptor
|
6
|
+
include ProtobufDescriptor::HasParent
|
7
|
+
include ProtobufDescriptor::NamedChild
|
8
|
+
include ProtobufDescriptor::HasChildren
|
9
|
+
|
10
10
|
# The containing {ProtobufDescriptor::FileDescriptor} or
|
11
11
|
# {ProtobufDescriptor::MessageDescriptor} that defines this enum.
|
12
12
|
attr_reader :parent
|
@@ -14,21 +14,27 @@ class ProtobufDescriptor
|
|
14
14
|
# The +EnumDescriptorProto+ this +EnumDescriptor+ is wrapping.
|
15
15
|
attr_reader :enum_descriptor_proto
|
16
16
|
|
17
|
+
# List of the enum values for this `EnumDescriptor` as a `NamedCollection`
|
18
|
+
# of {ProtobufDescriptor::EnumValueDescriptor}
|
19
|
+
attr_reader :value
|
20
|
+
alias_method :values, :value
|
21
|
+
|
22
|
+
register_children(:value, 2)
|
23
|
+
|
17
24
|
def initialize(parent, enum_descriptor_proto)
|
18
25
|
@parent = parent
|
19
26
|
@enum_descriptor_proto = enum_descriptor_proto
|
27
|
+
|
28
|
+
@value = ProtobufDescriptor::NamedCollection.new(
|
29
|
+
enum_descriptor_proto.value.map { |m|
|
30
|
+
ProtobufDescriptor::EnumValueDescriptor.new(self, m)
|
31
|
+
})
|
20
32
|
end
|
21
33
|
|
22
34
|
# The name of the enum
|
23
35
|
def name; enum_descriptor_proto.name; end
|
24
36
|
|
25
|
-
# The possible values of the enum
|
26
|
-
def value; enum_descriptor_proto.value; end
|
27
|
-
alias_method :values, :value
|
28
|
-
|
29
37
|
# The +EnumOptions+ defined for this enum
|
30
38
|
def options; enum_descriptor_proto.options; end
|
31
|
-
|
32
|
-
include NamedChild
|
33
39
|
end
|
34
40
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class ProtobufDescriptor
|
2
|
+
# Describes an enum type.
|
3
|
+
#
|
4
|
+
# See {+EnumValueDescriptorProto+}[https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#180]
|
5
|
+
class EnumValueDescriptor
|
6
|
+
include ProtobufDescriptor::HasParent
|
7
|
+
|
8
|
+
# The containing {ProtobufDescriptor::EnumDescriptor} that this is a value
|
9
|
+
# for.
|
10
|
+
attr_reader :parent
|
11
|
+
|
12
|
+
# The +EnumValueDescriptorProto+ this +EnumValueDescriptor+ is wrapping.
|
13
|
+
attr_reader :enum_value_descriptor_proto
|
14
|
+
|
15
|
+
def initialize(parent, enum_value_descriptor_proto)
|
16
|
+
@parent = parent
|
17
|
+
@enum_value_descriptor_proto = enum_value_descriptor_proto
|
18
|
+
end
|
19
|
+
|
20
|
+
# The name of the enum value
|
21
|
+
def name; enum_value_descriptor_proto.name; end
|
22
|
+
|
23
|
+
# The number mapped to the enum value
|
24
|
+
def number; enum_value_descriptor_proto.number; end
|
25
|
+
|
26
|
+
# The +EnumValueOptions+ defined for this enum
|
27
|
+
def options; enum_value_descriptor_proto.options; end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
class ProtobufDescriptor
|
2
|
+
# Describes a field within a message.
|
3
|
+
#
|
4
|
+
# See FieldDescriptorProto[https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#103]
|
5
|
+
class FieldDescriptor
|
6
|
+
include ProtobufDescriptor::HasParent
|
7
|
+
|
8
|
+
# The parent {ProtobufDescriptor::MessageDescriptor}
|
9
|
+
attr_reader :parent
|
10
|
+
# The +FieldDescriptorProto+ this +FieldDescriptor+ is wrapping.
|
11
|
+
attr_reader :field_descriptor_proto
|
12
|
+
|
13
|
+
def initialize(parent, field_descriptor_proto)
|
14
|
+
@parent = parent
|
15
|
+
@field_descriptor_proto = field_descriptor_proto
|
16
|
+
end
|
17
|
+
|
18
|
+
# The +FieldOptions+ for this field
|
19
|
+
def options
|
20
|
+
field_descriptor_proto.options
|
21
|
+
end
|
22
|
+
|
23
|
+
# Default value for this field.
|
24
|
+
# * For numeric types, contains the original text representation of the
|
25
|
+
# value.
|
26
|
+
# * For booleans, "true" or "false".
|
27
|
+
# * For strings, contains the default text contents (not escaped in any
|
28
|
+
# way).
|
29
|
+
# * For bytes, contains the C escaped value. All bytes >= 128 are
|
30
|
+
# escaped.
|
31
|
+
def default_value
|
32
|
+
field_descriptor_proto.default_value
|
33
|
+
end
|
34
|
+
|
35
|
+
# For extensions, this is the name of the type being extended. It is
|
36
|
+
# resolved in the same manner as type_name.
|
37
|
+
def extendee
|
38
|
+
field_descriptor_proto.extendee
|
39
|
+
end
|
40
|
+
|
41
|
+
# For message and enum types, this is the name of the type. If the name
|
42
|
+
# starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
|
43
|
+
# rules are used to find the type (i.e. first the nested types within this
|
44
|
+
# message are searched, then within the parent, on up to the root
|
45
|
+
# namespace).
|
46
|
+
#
|
47
|
+
# Note: the protocol buffer compiler always emits the fully qualified name!
|
48
|
+
def type_name
|
49
|
+
field_descriptor_proto.type_name
|
50
|
+
end
|
51
|
+
|
52
|
+
# Whether the field is optional/required/repeated.
|
53
|
+
def label
|
54
|
+
field_descriptor_proto.label
|
55
|
+
end
|
56
|
+
|
57
|
+
# The tag number of this field.
|
58
|
+
def number
|
59
|
+
field_descriptor_proto.number
|
60
|
+
end
|
61
|
+
|
62
|
+
# The name of this field.
|
63
|
+
def name
|
64
|
+
field_descriptor_proto.name
|
65
|
+
end
|
66
|
+
|
67
|
+
# If type_name is set, this need not be set. If both this and type_name
|
68
|
+
# are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
|
69
|
+
def field_type
|
70
|
+
field_descriptor_proto.type
|
71
|
+
end
|
72
|
+
|
73
|
+
# Resolves the field's +type_name+, returning the
|
74
|
+
# {ProtobufDescriptor::MessageDescriptor} or
|
75
|
+
# {ProtobufDescriptor::EnumDescriptor} that this field will represent.
|
76
|
+
def resolve_type
|
77
|
+
protobuf_descriptor.resolve_type_name(self.type_name, self.parent)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,16 +1,10 @@
|
|
1
|
-
require "protobuf_descriptor/enum_descriptor"
|
2
|
-
require "protobuf_descriptor/message_descriptor"
|
3
|
-
require "protobuf_descriptor/service_descriptor"
|
4
|
-
|
5
|
-
require "active_support"
|
6
|
-
require "active_support/core_ext/object/blank"
|
7
|
-
require "active_support/core_ext/string/inflections"
|
8
|
-
|
9
1
|
class ProtobufDescriptor
|
10
2
|
# Describes a complete .proto file.
|
11
3
|
#
|
12
4
|
# See {+FileDescriptorProto+}[https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#56]
|
13
5
|
class FileDescriptor
|
6
|
+
include ProtobufDescriptor::HasChildren
|
7
|
+
|
14
8
|
# The parent {ProtobufDescriptor}
|
15
9
|
attr_reader :file_descriptor_set
|
16
10
|
|
@@ -29,6 +23,12 @@ class ProtobufDescriptor
|
|
29
23
|
# NamedCollection of {ProtobufDescriptor::ServiceDescriptor}
|
30
24
|
attr_reader :service
|
31
25
|
|
26
|
+
# Field index is hard-coded since these are a bit annoying to grab
|
27
|
+
# consistently with the different protocol buffer implementations.
|
28
|
+
self.register_children(:message_type, 4)
|
29
|
+
self.register_children(:enum_type, 5)
|
30
|
+
self.register_children(:service, 6)
|
31
|
+
|
32
32
|
def initialize(file_descriptor_set, file_descriptor_proto) #:nodoc:
|
33
33
|
# This is basically a parent pointer.
|
34
34
|
@file_descriptor_set = file_descriptor_set
|
@@ -55,11 +55,13 @@ class ProtobufDescriptor
|
|
55
55
|
alias_method :enums, :enum_types
|
56
56
|
alias_method :services, :service
|
57
57
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
# Whether source code info is associated with this descriptor
|
59
|
+
def has_source_code_info?
|
60
|
+
file_descriptor_proto.has_field?(:source_code_info)
|
61
|
+
end
|
62
|
+
|
63
|
+
def source_code_info
|
64
|
+
file_descriptor_proto.source_code_info
|
63
65
|
end
|
64
66
|
|
65
67
|
# Filename relative to root of source tree.
|
@@ -77,7 +79,7 @@ class ProtobufDescriptor
|
|
77
79
|
# inappropriate because proto packages do not normally start with backwards
|
78
80
|
# domain names.
|
79
81
|
def java_package
|
80
|
-
if file_descriptor_proto.has_field?(:options) && file_descriptor_proto.options.java_package
|
82
|
+
if file_descriptor_proto.has_field?(:options) && present?(file_descriptor_proto.options.java_package)
|
81
83
|
return file_descriptor_proto.options.java_package
|
82
84
|
else
|
83
85
|
return file_descriptor_proto.package
|
@@ -90,14 +92,14 @@ class ProtobufDescriptor
|
|
90
92
|
# a .proto always translates to a single class, but you may want to
|
91
93
|
# explicitly choose the class name).
|
92
94
|
def java_outer_classname
|
93
|
-
if file_descriptor_proto.has_field?(:options) && file_descriptor_proto.options.java_multiple_files
|
95
|
+
if file_descriptor_proto.has_field?(:options) && present?(file_descriptor_proto.options.java_multiple_files)
|
94
96
|
return nil
|
95
|
-
elsif file_descriptor_proto.has_field?(:options) && file_descriptor_proto.options.java_outer_classname
|
97
|
+
elsif file_descriptor_proto.has_field?(:options) && present?(file_descriptor_proto.options.java_outer_classname)
|
96
98
|
return file_descriptor_proto.options.java_outer_classname
|
97
99
|
else
|
98
100
|
basename = name.split('/').last
|
99
101
|
basename = basename.gsub('.proto', '')
|
100
|
-
return basename
|
102
|
+
return camelize(basename)
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
@@ -123,5 +125,23 @@ class ProtobufDescriptor
|
|
123
125
|
def fully_qualified_ruby_name
|
124
126
|
return "::#{self.package.gsub('.', '::')}"
|
125
127
|
end
|
128
|
+
|
129
|
+
private
|
130
|
+
# Copy over a bunch of methods that are normally part of active_support:
|
131
|
+
def present?(string)
|
132
|
+
return !blank?(string)
|
133
|
+
end
|
134
|
+
|
135
|
+
def blank?(string)
|
136
|
+
string.respond_to?(:empty?) ? !!string.empty? : !string
|
137
|
+
end
|
138
|
+
|
139
|
+
def camelize(string)
|
140
|
+
if string.respond_to?(:camelize)
|
141
|
+
return string.camelize
|
142
|
+
else
|
143
|
+
return string.split("_").map { |s| s.capitalize }.join("")
|
144
|
+
end
|
145
|
+
end
|
126
146
|
end
|
127
147
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class ProtobufDescriptor
|
2
|
+
# Mixin module to support classes with different "kinds" of children
|
3
|
+
module HasChildren
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# To be called by the containing class, registers a set of children
|
10
|
+
def register_children(children_method, child_kind_id)
|
11
|
+
@registered_children ||= Hash.new { |h, k| h[k] = [] }
|
12
|
+
|
13
|
+
@registered_children[child_kind_id] = children_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def registered_children
|
17
|
+
return @registered_children
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def named_children
|
22
|
+
return @named_children if @named_children
|
23
|
+
|
24
|
+
@named_children = NamedCollection.new([])
|
25
|
+
|
26
|
+
self.class.registered_children.each do |id, method|
|
27
|
+
collection = self.send(method)
|
28
|
+
collection = collection.is_a?(NamedCollection) ? collection.collection : collection
|
29
|
+
collection.each do |m|
|
30
|
+
@named_children << m if m.is_a?(NamedChild)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return @named_children
|
34
|
+
end
|
35
|
+
|
36
|
+
# Computes the "relative path" from this node to one of its direct children
|
37
|
+
# according to the rules specified by
|
38
|
+
# [descriptor.proto line 506](https://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto#506).
|
39
|
+
def compute_source_code_info_path_component(child)
|
40
|
+
self.class.registered_children.each do |kind_id, collection|
|
41
|
+
idx = self.send(collection).find_index(child)
|
42
|
+
if !idx.nil?
|
43
|
+
return [kind_id, idx]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
raise "Could not find #{child} in #{self}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,4 +1,11 @@
|
|
1
1
|
class ProtobufDescriptor
|
2
|
+
# Mixin module to make accessing ancestors easier.
|
3
|
+
#
|
4
|
+
# Also has a random method for computing the source code info path (as well as
|
5
|
+
# methods that rely on it to do things like grab comments and the like.)
|
6
|
+
#
|
7
|
+
# Classes that include this module must respond_to `parent`, in addition their
|
8
|
+
# parent include `HasChildren`
|
2
9
|
module HasParent
|
3
10
|
def file_descriptor
|
4
11
|
p = self.parent
|
@@ -15,5 +22,40 @@ class ProtobufDescriptor
|
|
15
22
|
end
|
16
23
|
return p
|
17
24
|
end
|
25
|
+
|
26
|
+
def compute_source_code_info_path
|
27
|
+
path_component = parent.compute_source_code_info_path_component(self)
|
28
|
+
parent_path = if parent.class.name == "ProtobufDescriptor::FileDescriptor"
|
29
|
+
[]
|
30
|
+
else
|
31
|
+
parent.compute_source_code_info_path
|
32
|
+
end
|
33
|
+
return parent_path + path_component
|
34
|
+
end
|
35
|
+
|
36
|
+
def source_code_info_locations
|
37
|
+
raise "No source code info attached!" unless file_descriptor.has_source_code_info?
|
38
|
+
|
39
|
+
source_code_info_path = compute_source_code_info_path
|
40
|
+
return file_descriptor.source_code_info.location.select { |location|
|
41
|
+
location.path == source_code_info_path
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def source_code_info_location
|
46
|
+
return source_code_info_locations.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def source_code_info_span
|
50
|
+
return source_code_info_location.span
|
51
|
+
end
|
52
|
+
|
53
|
+
def leading_comments
|
54
|
+
return source_code_info_location.leading_comments
|
55
|
+
end
|
56
|
+
|
57
|
+
def trailing_comments
|
58
|
+
return source_code_info_location.trailing_comments
|
59
|
+
end
|
18
60
|
end
|
19
61
|
end
|