protostar 0.1.0.beta1
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 +7 -0
- data/CHANGELOG.md +60 -0
- data/LICENSE.txt +21 -0
- data/README.md +647 -0
- data/THIRD_PARTY_NOTICES.md +61 -0
- data/exe/protoc-gen-protostar +7 -0
- data/exe/protostar +7 -0
- data/lib/protostar/builder/generator.rb +71 -0
- data/lib/protostar/builder/sink.rb +35 -0
- data/lib/protostar/builder.rb +965 -0
- data/lib/protostar/cli.rb +267 -0
- data/lib/protostar/codec/decode_generator.rb +199 -0
- data/lib/protostar/codec/decoder.rb +296 -0
- data/lib/protostar/codec/encode_generator.rb +224 -0
- data/lib/protostar/codec/encoder.rb +121 -0
- data/lib/protostar/codec/sizer.rb +91 -0
- data/lib/protostar/codec.rb +15 -0
- data/lib/protostar/compiler/ast.rb +193 -0
- data/lib/protostar/compiler/emitters/descriptor_set.rb +57 -0
- data/lib/protostar/compiler/emitters/google_ruby.rb +103 -0
- data/lib/protostar/compiler/emitters/grpc.rb +175 -0
- data/lib/protostar/compiler/emitters/protostar_rbs.rb +252 -0
- data/lib/protostar/compiler/emitters/rbs.rb +394 -0
- data/lib/protostar/compiler/emitters/ruby.rb +503 -0
- data/lib/protostar/compiler/emitters.rb +268 -0
- data/lib/protostar/compiler/include/LICENSE +32 -0
- data/lib/protostar/compiler/include/google/protobuf/any.proto +106 -0
- data/lib/protostar/compiler/include/google/protobuf/api.proto +229 -0
- data/lib/protostar/compiler/include/google/protobuf/compiler/plugin.proto +180 -0
- data/lib/protostar/compiler/include/google/protobuf/cpp_features.proto +87 -0
- data/lib/protostar/compiler/include/google/protobuf/descriptor.proto +1532 -0
- data/lib/protostar/compiler/include/google/protobuf/duration.proto +115 -0
- data/lib/protostar/compiler/include/google/protobuf/empty.proto +51 -0
- data/lib/protostar/compiler/include/google/protobuf/field_mask.proto +243 -0
- data/lib/protostar/compiler/include/google/protobuf/java_features.proto +132 -0
- data/lib/protostar/compiler/include/google/protobuf/source_context.proto +48 -0
- data/lib/protostar/compiler/include/google/protobuf/struct.proto +111 -0
- data/lib/protostar/compiler/include/google/protobuf/timestamp.proto +145 -0
- data/lib/protostar/compiler/include/google/protobuf/type.proto +217 -0
- data/lib/protostar/compiler/include/google/protobuf/wrappers.proto +157 -0
- data/lib/protostar/compiler/lexer.rb +659 -0
- data/lib/protostar/compiler/linker.rb +894 -0
- data/lib/protostar/compiler/option_interpreter.rb +363 -0
- data/lib/protostar/compiler/parser.rb +1696 -0
- data/lib/protostar/compiler/retention.rb +104 -0
- data/lib/protostar/compiler/run.rb +184 -0
- data/lib/protostar/compiler/source_info.rb +161 -0
- data/lib/protostar/compiler/symbol_table.rb +223 -0
- data/lib/protostar/compiler/text_format.rb +340 -0
- data/lib/protostar/compiler/validator.rb +944 -0
- data/lib/protostar/compiler.rb +304 -0
- data/lib/protostar/diagnostics/codes.rb +1307 -0
- data/lib/protostar/diagnostics/formats.rb +64 -0
- data/lib/protostar/diagnostics/renderer.rb +240 -0
- data/lib/protostar/diagnostics/source.rb +153 -0
- data/lib/protostar/diagnostics.rb +117 -0
- data/lib/protostar/dsl.rb +367 -0
- data/lib/protostar/enum.rb +70 -0
- data/lib/protostar/errors.rb +23 -0
- data/lib/protostar/google/protobuf/any_pb.rb +90 -0
- data/lib/protostar/google/protobuf/api_pb.rb +199 -0
- data/lib/protostar/google/protobuf/compiler/plugin_pb.rb +168 -0
- data/lib/protostar/google/protobuf/descriptor_pb.rb +1239 -0
- data/lib/protostar/google/protobuf/duration_pb.rb +99 -0
- data/lib/protostar/google/protobuf/empty_pb.rb +36 -0
- data/lib/protostar/google/protobuf/field_mask_pb.rb +228 -0
- data/lib/protostar/google/protobuf/source_context_pb.rb +33 -0
- data/lib/protostar/google/protobuf/struct_pb.rb +91 -0
- data/lib/protostar/google/protobuf/timestamp_pb.rb +129 -0
- data/lib/protostar/google/protobuf/type_pb.rb +202 -0
- data/lib/protostar/google/protobuf/wrappers_pb.rb +125 -0
- data/lib/protostar/google_protobuf_shim.rb +24 -0
- data/lib/protostar/json/encoder.rb +340 -0
- data/lib/protostar/json/errors.rb +34 -0
- data/lib/protostar/json/parser.rb +437 -0
- data/lib/protostar/json/path.rb +39 -0
- data/lib/protostar/json.rb +95 -0
- data/lib/protostar/lint/command.rb +197 -0
- data/lib/protostar/lint/config.rb +98 -0
- data/lib/protostar/lint/context.rb +126 -0
- data/lib/protostar/lint/directives.rb +56 -0
- data/lib/protostar/lint/fixer.rb +165 -0
- data/lib/protostar/lint/naming.rb +54 -0
- data/lib/protostar/lint/rule.rb +120 -0
- data/lib/protostar/lint/rules/comment_enum.rb +31 -0
- data/lib/protostar/lint/rules/comment_enum_value.rb +32 -0
- data/lib/protostar/lint/rules/comment_field.rb +33 -0
- data/lib/protostar/lint/rules/comment_message.rb +31 -0
- data/lib/protostar/lint/rules/comment_rpc.rb +31 -0
- data/lib/protostar/lint/rules/comment_service.rb +31 -0
- data/lib/protostar/lint/rules/edition_recommended.rb +31 -0
- data/lib/protostar/lint/rules/enum_first_value_zero.rb +34 -0
- data/lib/protostar/lint/rules/enum_pascal_case.rb +25 -0
- data/lib/protostar/lint/rules/enum_value_prefix.rb +38 -0
- data/lib/protostar/lint/rules/enum_value_upper_snake_case.rb +28 -0
- data/lib/protostar/lint/rules/enum_zero_value_suffix.rb +41 -0
- data/lib/protostar/lint/rules/field_lower_snake_case.rb +34 -0
- data/lib/protostar/lint/rules/field_not_required.rb +39 -0
- data/lib/protostar/lint/rules/field_number_reuse_risk.rb +45 -0
- data/lib/protostar/lint/rules/field_numbers_hot_range.rb +44 -0
- data/lib/protostar/lint/rules/file_lower_snake_case.rb +27 -0
- data/lib/protostar/lint/rules/import_no_public.rb +29 -0
- data/lib/protostar/lint/rules/import_no_weak.rb +28 -0
- data/lib/protostar/lint/rules/import_used.rb +33 -0
- data/lib/protostar/lint/rules/message_pascal_case.rb +27 -0
- data/lib/protostar/lint/rules/no_deprecated_features.rb +50 -0
- data/lib/protostar/lint/rules/no_groups.rb +34 -0
- data/lib/protostar/lint/rules/oneof_lower_snake_case.rb +27 -0
- data/lib/protostar/lint/rules/package_defined.rb +28 -0
- data/lib/protostar/lint/rules/package_directory_match.rb +33 -0
- data/lib/protostar/lint/rules/package_lower_snake_case.rb +28 -0
- data/lib/protostar/lint/rules/package_same_directory.rb +39 -0
- data/lib/protostar/lint/rules/package_version_suffix.rb +31 -0
- data/lib/protostar/lint/rules/reserved_names_with_numbers.rb +44 -0
- data/lib/protostar/lint/rules/rpc_pascal_case.rb +25 -0
- data/lib/protostar/lint/rules/rpc_request_response_unique.rb +40 -0
- data/lib/protostar/lint/rules/rpc_request_standard_name.rb +32 -0
- data/lib/protostar/lint/rules/rpc_response_standard_name.rb +31 -0
- data/lib/protostar/lint/rules/service_pascal_case.rb +25 -0
- data/lib/protostar/lint/rules/service_suffix.rb +28 -0
- data/lib/protostar/lint/rules/syntax_specified.rb +35 -0
- data/lib/protostar/lint/runner.rb +135 -0
- data/lib/protostar/lint.rb +122 -0
- data/lib/protostar/message/accessors.rb +86 -0
- data/lib/protostar/message/coercion.rb +171 -0
- data/lib/protostar/message/field_info.rb +145 -0
- data/lib/protostar/message/reflection.rb +149 -0
- data/lib/protostar/message.rb +572 -0
- data/lib/protostar/plugin.rb +94 -0
- data/lib/protostar/schema/default_value.rb +113 -0
- data/lib/protostar/schema/descriptor.rb +41 -0
- data/lib/protostar/schema/draft/copy.rb +88 -0
- data/lib/protostar/schema/draft/resolution.rb +177 -0
- data/lib/protostar/schema/draft.rb +779 -0
- data/lib/protostar/schema/enum.rb +106 -0
- data/lib/protostar/schema/extension_range.rb +37 -0
- data/lib/protostar/schema/features.rb +153 -0
- data/lib/protostar/schema/field.rb +201 -0
- data/lib/protostar/schema/file.rb +217 -0
- data/lib/protostar/schema/freezer.rb +61 -0
- data/lib/protostar/schema/message.rb +104 -0
- data/lib/protostar/schema/oneof.rb +38 -0
- data/lib/protostar/schema/options.rb +367 -0
- data/lib/protostar/schema/pool.rb +179 -0
- data/lib/protostar/schema/proto.rb +576 -0
- data/lib/protostar/schema/resolver.rb +118 -0
- data/lib/protostar/schema/service.rb +89 -0
- data/lib/protostar/schema/source_info.rb +53 -0
- data/lib/protostar/schema.rb +65 -0
- data/lib/protostar/short_names/any.rb +7 -0
- data/lib/protostar/short_names/duration.rb +7 -0
- data/lib/protostar/short_names/empty.rb +7 -0
- data/lib/protostar/short_names/field_mask.rb +7 -0
- data/lib/protostar/short_names/struct.rb +9 -0
- data/lib/protostar/short_names/timestamp.rb +7 -0
- data/lib/protostar/short_names/wrappers.rb +15 -0
- data/lib/protostar/text/extensions.rb +114 -0
- data/lib/protostar/text/parser.rb +439 -0
- data/lib/protostar/text/printer.rb +304 -0
- data/lib/protostar/text/tokenizer.rb +116 -0
- data/lib/protostar/text.rb +67 -0
- data/lib/protostar/types.rb +152 -0
- data/lib/protostar/unknown_field.rb +58 -0
- data/lib/protostar/version.rb +5 -0
- data/lib/protostar/view/generator.rb +298 -0
- data/lib/protostar/view/map.rb +194 -0
- data/lib/protostar/view/repeated.rb +143 -0
- data/lib/protostar/view/scan.rb +183 -0
- data/lib/protostar/view.rb +283 -0
- data/lib/protostar/well_known/any.rb +52 -0
- data/lib/protostar/well_known/duration.rb +53 -0
- data/lib/protostar/well_known/list_value.rb +63 -0
- data/lib/protostar/well_known/struct.rb +55 -0
- data/lib/protostar/well_known/timestamp.rb +64 -0
- data/lib/protostar/well_known/value.rb +60 -0
- data/lib/protostar/well_known.rb +38 -0
- data/lib/protostar/wire/io_source.rb +40 -0
- data/lib/protostar/wire/reader.rb +254 -0
- data/lib/protostar/wire/writer.rb +201 -0
- data/lib/protostar/wire.rb +96 -0
- data/lib/protostar.rb +95 -0
- data/shims/google-protobuf/lib/google/protobuf/any_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/api_pb.rb +22 -0
- data/shims/google-protobuf/lib/google/protobuf/compiler/plugin_pb.rb +25 -0
- data/shims/google-protobuf/lib/google/protobuf/descriptor_pb.rb +72 -0
- data/shims/google-protobuf/lib/google/protobuf/descriptor_pool.rb +164 -0
- data/shims/google-protobuf/lib/google/protobuf/descriptors.rb +553 -0
- data/shims/google-protobuf/lib/google/protobuf/duration_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/empty_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/field_mask_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/internal/convert.rb +180 -0
- data/shims/google-protobuf/lib/google/protobuf/internal/extensions.rb +154 -0
- data/shims/google-protobuf/lib/google/protobuf/internal/json.rb +104 -0
- data/shims/google-protobuf/lib/google/protobuf/internal/well_known.rb +140 -0
- data/shims/google-protobuf/lib/google/protobuf/map.rb +216 -0
- data/shims/google-protobuf/lib/google/protobuf/message.rb +544 -0
- data/shims/google-protobuf/lib/google/protobuf/message_exts.rb +41 -0
- data/shims/google-protobuf/lib/google/protobuf/plugin_pb.rb +4 -0
- data/shims/google-protobuf/lib/google/protobuf/repeated_field.rb +366 -0
- data/shims/google-protobuf/lib/google/protobuf/source_context_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/struct_pb.rb +20 -0
- data/shims/google-protobuf/lib/google/protobuf/timestamp_pb.rb +17 -0
- data/shims/google-protobuf/lib/google/protobuf/type_pb.rb +27 -0
- data/shims/google-protobuf/lib/google/protobuf/well_known_types.rb +37 -0
- data/shims/google-protobuf/lib/google/protobuf/wrappers_pb.rb +25 -0
- data/shims/google-protobuf/lib/google/protobuf.rb +107 -0
- data/shims/google-protobuf/lib/google/protobuf_ffi.rb +5 -0
- data/shims/google-protobuf/lib/google/protobuf_native.rb +5 -0
- data/sig/protostar/google/protobuf/any_pb.rbs +77 -0
- data/sig/protostar/google/protobuf/api_pb.rbs +242 -0
- data/sig/protostar/google/protobuf/compiler/plugin_pb.rbs +264 -0
- data/sig/protostar/google/protobuf/descriptor_pb.rbs +2220 -0
- data/sig/protostar/google/protobuf/duration_pb.rbs +82 -0
- data/sig/protostar/google/protobuf/empty_pb.rbs +18 -0
- data/sig/protostar/google/protobuf/field_mask_pb.rbs +170 -0
- data/sig/protostar/google/protobuf/source_context_pb.rbs +24 -0
- data/sig/protostar/google/protobuf/struct_pb.rbs +135 -0
- data/sig/protostar/google/protobuf/timestamp_pb.rbs +102 -0
- data/sig/protostar/google/protobuf/type_pb.rbs +304 -0
- data/sig/protostar/google/protobuf/wrappers_pb.rbs +169 -0
- data/sig/protostar/lint.rbs +216 -0
- data/sig/protostar.rbs +326 -0
- metadata +366 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
class Compiler
|
|
5
|
+
module Emitters
|
|
6
|
+
# Writes `_pb.rbs` signatures for the classes {Ruby} generates:
|
|
7
|
+
# subclasses of `Protostar::Message`, repeated fields as Arrays, maps as
|
|
8
|
+
# Hashes, writers typed as {Message::Coercion} accepts. Signatures for
|
|
9
|
+
# `Protostar::Message` itself are in the gem's `sig/protostar.rbs`.
|
|
10
|
+
# {Rbs} writes protoc's signatures for google-protobuf's classes instead.
|
|
11
|
+
class ProtostarRbs
|
|
12
|
+
INTEGERS = %i[fixed32 fixed64 int32 int64 sfixed32 sfixed64 sint32 sint64 uint32 uint64].freeze
|
|
13
|
+
# The mixins {WellKnown::MIXINS} includes, by full name, as RBS names
|
|
14
|
+
MIXINS = {
|
|
15
|
+
"google.protobuf.Any" => "::Protostar::WellKnown::Any",
|
|
16
|
+
"google.protobuf.Timestamp" => "::Protostar::WellKnown::Timestamp",
|
|
17
|
+
"google.protobuf.Duration" => "::Protostar::WellKnown::Duration",
|
|
18
|
+
"google.protobuf.Struct" => "::Protostar::WellKnown::Struct",
|
|
19
|
+
"google.protobuf.Value" => "::Protostar::WellKnown::Value",
|
|
20
|
+
"google.protobuf.ListValue" => "::Protostar::WellKnown::ListValue"
|
|
21
|
+
}.freeze
|
|
22
|
+
# Ruby values {Message::Coercion} turns into these messages
|
|
23
|
+
COERCED = {
|
|
24
|
+
"google.protobuf.Timestamp" => "::Time",
|
|
25
|
+
"google.protobuf.Duration" => "::Numeric"
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
# @param namespaces [Hash{String => String}] Ruby module paths by file name, as {Ruby} takes them
|
|
29
|
+
def initialize(namespaces: {})
|
|
30
|
+
@namespaces = namespaces
|
|
31
|
+
@reserved = Message::Accessors.reserved
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @param files [Array<Schema::File>]
|
|
35
|
+
# @return [Hash{String => String}] output path to signatures
|
|
36
|
+
def emit(files)
|
|
37
|
+
files.to_h { |f| [Naming.require_name(f.name) + ".rbs", file(f)] }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @param file [Schema::File]
|
|
41
|
+
# @return [String]
|
|
42
|
+
def file(file)
|
|
43
|
+
Naming.check_ruby_package(file)
|
|
44
|
+
@source = file.source_info
|
|
45
|
+
p = Printer.new
|
|
46
|
+
p.print("# Generated by protostar from #{file.name}. Do not edit.\n")
|
|
47
|
+
modules = module_path(file)
|
|
48
|
+
unless file.messages.empty? && file.enums.empty?
|
|
49
|
+
p.print("\n")
|
|
50
|
+
modules.each do |m|
|
|
51
|
+
p.print("module #{m}\n")
|
|
52
|
+
p.indent
|
|
53
|
+
end
|
|
54
|
+
first = [true]
|
|
55
|
+
file.messages.each_with_index { |m, i| message(p, m, [4, i], first) }
|
|
56
|
+
file.enums.each_with_index { |e, i| enum(p, e, [5, i], first) }
|
|
57
|
+
modules.size.times do
|
|
58
|
+
p.outdent
|
|
59
|
+
p.print("end\n")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
p.to_s
|
|
63
|
+
ensure
|
|
64
|
+
@source = nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def module_path(file)
|
|
70
|
+
namespace = @namespaces[file.name]
|
|
71
|
+
namespace ||= "Protostar::#{Naming.module_path(file).join("::")}" if BOOTSTRAP.include?(file.name)
|
|
72
|
+
Naming.module_path(file, namespace)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def constant(descriptor)
|
|
76
|
+
prefix = module_path(descriptor.file).map { |m| "::#{m}" }.join
|
|
77
|
+
"#{prefix}::#{Naming.relative_constant(descriptor)}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def blank(p, first)
|
|
81
|
+
if first[0]
|
|
82
|
+
first[0] = false
|
|
83
|
+
else
|
|
84
|
+
p.print("\n")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def comment(p, path)
|
|
89
|
+
text = @source&.location(path)&.leading_comments
|
|
90
|
+
return if text.nil? || text.empty?
|
|
91
|
+
text.split("\n").reject(&:empty?).each { |line| p.print("##{line}\n") }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def message?(field)
|
|
95
|
+
field.type == :message || field.type == :group
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# What the reader returns for one value
|
|
99
|
+
def read_one(field)
|
|
100
|
+
case field.type
|
|
101
|
+
when :double, :float then "::Float"
|
|
102
|
+
when *INTEGERS then "::Integer"
|
|
103
|
+
when :bool then "bool"
|
|
104
|
+
when :string, :bytes then "::String"
|
|
105
|
+
when :enum then "#{constant(field.enum_type)}::names | ::Integer"
|
|
106
|
+
else constant(field.message_type)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# What the writer takes for one value
|
|
111
|
+
def write_one(field)
|
|
112
|
+
case field.type
|
|
113
|
+
when :double, :float then "::Float | ::Integer"
|
|
114
|
+
when *INTEGERS then "::Integer"
|
|
115
|
+
when :bool then "bool"
|
|
116
|
+
when :string, :bytes then "::String"
|
|
117
|
+
when :enum then "#{constant(field.enum_type)}::names | ::Integer"
|
|
118
|
+
else
|
|
119
|
+
name = constant(field.message_type)
|
|
120
|
+
[name, "#{name}::init_map", COERCED[field.message_type.full_name]].compact.join(" | ")
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def read_type(field)
|
|
125
|
+
if field.map?
|
|
126
|
+
"::Hash[#{read_one(field.map_key)}, #{read_one(field.map_value)}]"
|
|
127
|
+
elsif field.repeated?
|
|
128
|
+
"::Array[#{read_one(field)}]"
|
|
129
|
+
elsif message?(field)
|
|
130
|
+
"#{constant(field.message_type)}?"
|
|
131
|
+
else
|
|
132
|
+
read_one(field)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def write_type(field)
|
|
137
|
+
inner = if field.map?
|
|
138
|
+
"::Hash[#{write_one(field.map_key)}, #{write_one(field.map_value)}]"
|
|
139
|
+
elsif field.repeated?
|
|
140
|
+
"::Array[#{write_one(field)}]"
|
|
141
|
+
else
|
|
142
|
+
write_one(field)
|
|
143
|
+
end
|
|
144
|
+
inner.include?("|") ? "(#{inner})?" : "#{inner}?"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def enum(p, enum, path, first)
|
|
148
|
+
blank(p, first)
|
|
149
|
+
comment(p, path)
|
|
150
|
+
p.print("module #{Naming.rubify_constant(enum.name)}\n")
|
|
151
|
+
p.indent
|
|
152
|
+
p.print("extend ::Protostar::Enum\n\n")
|
|
153
|
+
seen = {}
|
|
154
|
+
enum.values.each do |v|
|
|
155
|
+
const = Protostar::Enum.constant_name(v.name)
|
|
156
|
+
next if const.nil? || seen[const]
|
|
157
|
+
seen[const] = true
|
|
158
|
+
p.print("#{const}: #{v.number}\n")
|
|
159
|
+
end
|
|
160
|
+
p.print("\ntype names = #{enum.values.map { |v| ":#{symbol(v.name)}" }.uniq.join(" | ")}\n")
|
|
161
|
+
p.outdent
|
|
162
|
+
p.print("end\n")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# A Symbol literal for a name, quoted when RBS needs it
|
|
166
|
+
def symbol(name)
|
|
167
|
+
/\A[A-Za-z_][A-Za-z0-9_]*\z/.match?(name) ? name : name.inspect
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def message(p, message, path, first)
|
|
171
|
+
return if message.map_entry?
|
|
172
|
+
blank(p, first)
|
|
173
|
+
comment(p, path)
|
|
174
|
+
p.print("class #{Naming.rubify_constant(message.name)} < ::Protostar::Message\n")
|
|
175
|
+
p.indent
|
|
176
|
+
inner = [true]
|
|
177
|
+
message.nested_messages.each_with_index { |m, i| message(p, m, path + [3, i], inner) }
|
|
178
|
+
message.nested_enums.each_with_index { |e, i| enum(p, e, path + [4, i], inner) }
|
|
179
|
+
blank(p, inner)
|
|
180
|
+
if (mixin = MIXINS[message.full_name])
|
|
181
|
+
p.print("include #{mixin}\nextend #{mixin}::ClassMethods\n\n")
|
|
182
|
+
end
|
|
183
|
+
init_map(p, message)
|
|
184
|
+
constructor(p, message)
|
|
185
|
+
taken = @reserved.dup
|
|
186
|
+
message.fields.each_with_index do |f, i|
|
|
187
|
+
accessors(p, f, path + [2, i], taken)
|
|
188
|
+
end
|
|
189
|
+
message.real_oneofs.each do |o|
|
|
190
|
+
which = :"which_#{o.name}"
|
|
191
|
+
next if taken[which]
|
|
192
|
+
taken[which] = true
|
|
193
|
+
names = o.fields.map { |f| ":#{f.name}" }.uniq.join(" | ")
|
|
194
|
+
p.print("def which_#{o.name}: () -> (#{names})?\n")
|
|
195
|
+
end
|
|
196
|
+
p.outdent
|
|
197
|
+
p.print("end\n")
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def init_map(p, message)
|
|
201
|
+
if message.fields.empty?
|
|
202
|
+
p.print("type init_map = ::Hash[::Symbol | ::String, untyped]\n")
|
|
203
|
+
return
|
|
204
|
+
end
|
|
205
|
+
p.print("type init_map = {\n")
|
|
206
|
+
p.indent
|
|
207
|
+
message.fields.each_with_index do |f, i|
|
|
208
|
+
comma = (i == message.fields.size - 1) ? "" : ","
|
|
209
|
+
p.print("?#{f.name}: #{write_type(f)}#{comma}\n")
|
|
210
|
+
end
|
|
211
|
+
p.outdent
|
|
212
|
+
p.print("}\n")
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# `new` takes a Hash, keywords, or both
|
|
216
|
+
def constructor(p, message)
|
|
217
|
+
if message.fields.empty?
|
|
218
|
+
p.print("def initialize: (?init_map? fields, **untyped) -> void\n")
|
|
219
|
+
return
|
|
220
|
+
end
|
|
221
|
+
p.print("def initialize: (\n")
|
|
222
|
+
p.indent
|
|
223
|
+
p.print("?init_map? fields")
|
|
224
|
+
message.fields.each { |f| p.print(",\n?#{f.name}: #{write_type(f)}") }
|
|
225
|
+
p.outdent
|
|
226
|
+
p.print("\n) -> void\n")
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def accessors(p, field, path, taken)
|
|
230
|
+
name = field.name
|
|
231
|
+
read = read_type(field)
|
|
232
|
+
write = write_type(field)
|
|
233
|
+
reader = !taken[name.to_sym]
|
|
234
|
+
writer = !taken[:"#{name}="]
|
|
235
|
+
taken[name.to_sym] = taken[:"#{name}="] = true
|
|
236
|
+
if reader || writer
|
|
237
|
+
p.print("\n")
|
|
238
|
+
comment(p, path)
|
|
239
|
+
p.print("attr_reader #{name}(): #{read}\n") if reader
|
|
240
|
+
p.print("attr_writer #{name}(): #{write}\n") if writer
|
|
241
|
+
end
|
|
242
|
+
return unless field.presence?
|
|
243
|
+
has = :"has_#{name}?"
|
|
244
|
+
clear = :"clear_#{name}"
|
|
245
|
+
p.print("def #{has}: () -> bool\n") unless taken[has]
|
|
246
|
+
p.print("def #{clear}: () -> void\n") unless taken[clear]
|
|
247
|
+
taken[has] = taken[clear] = true
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
class Compiler
|
|
5
|
+
module Emitters
|
|
6
|
+
# Writes the `_pb.rbs` signatures protoc's rbs_generator.cc writes.
|
|
7
|
+
# Leading comments come from source info, so compile with it.
|
|
8
|
+
class Rbs
|
|
9
|
+
WRAPPERS = %w[
|
|
10
|
+
google.protobuf.DoubleValue google.protobuf.FloatValue google.protobuf.Int64Value
|
|
11
|
+
google.protobuf.UInt64Value google.protobuf.Int32Value google.protobuf.UInt32Value
|
|
12
|
+
google.protobuf.StringValue google.protobuf.BytesValue google.protobuf.BoolValue
|
|
13
|
+
].freeze
|
|
14
|
+
INTEGERS = %i[fixed32 fixed64 int32 int64 sfixed32 sfixed64 sint32 sint64 uint32 uint64].freeze
|
|
15
|
+
HEADER = "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" \
|
|
16
|
+
"# This RBS interface is provided for convenience, on a best-effort basis.\n" \
|
|
17
|
+
"# The library is the definitive source for the API contract; if the RBS file\n" \
|
|
18
|
+
"# and the library's behavior differ, the library behavior is authoritative.\n" \
|
|
19
|
+
"# We welcome fixes to change the RBS file to match.\n"
|
|
20
|
+
|
|
21
|
+
# @param files [Array<Schema::File>]
|
|
22
|
+
# @return [Hash{String => String}] output path to signatures
|
|
23
|
+
def emit(files)
|
|
24
|
+
files.to_h { |f| [Naming.require_name(f.name) + ".rbs", file(f)] }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param file [Schema::File]
|
|
28
|
+
# @return [String]
|
|
29
|
+
def file(file)
|
|
30
|
+
Naming.check_ruby_package(file)
|
|
31
|
+
@source = file.source_info
|
|
32
|
+
p = Printer.new
|
|
33
|
+
p.print("#{HEADER}# source: #{file.name}\n\n")
|
|
34
|
+
initial = [true]
|
|
35
|
+
modules = Naming.module_path(file)
|
|
36
|
+
modules.each do |m|
|
|
37
|
+
p.print("module #{m}\n")
|
|
38
|
+
p.indent
|
|
39
|
+
end
|
|
40
|
+
file.messages.each_with_index do |m, i|
|
|
41
|
+
mid_line(initial, p)
|
|
42
|
+
message(p, m, [4, i])
|
|
43
|
+
end
|
|
44
|
+
file.enums.each_with_index do |e, i|
|
|
45
|
+
mid_line(initial, p)
|
|
46
|
+
enum(p, e, [5, i])
|
|
47
|
+
end
|
|
48
|
+
modules.size.times do
|
|
49
|
+
p.outdent
|
|
50
|
+
p.print("end\n")
|
|
51
|
+
end
|
|
52
|
+
p.print("\n")
|
|
53
|
+
lookup_override(p, file)
|
|
54
|
+
p.to_s
|
|
55
|
+
ensure
|
|
56
|
+
@source = nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def mid_line(initial, p)
|
|
62
|
+
if initial[0]
|
|
63
|
+
initial[0] = false
|
|
64
|
+
else
|
|
65
|
+
p.print("\n")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def separator(initial)
|
|
70
|
+
if initial[0]
|
|
71
|
+
initial[0] = false
|
|
72
|
+
" "
|
|
73
|
+
else
|
|
74
|
+
"| "
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def wrap_union(type)
|
|
79
|
+
type.include?("|") ? "(#{type})" : type
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def optional(type)
|
|
83
|
+
type.end_with?("?") ? type : "#{wrap_union(type)}?"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def comment(p, path)
|
|
87
|
+
text = @source&.location(path)&.leading_comments
|
|
88
|
+
return if text.nil? || text.empty?
|
|
89
|
+
text.split("\n").reject(&:empty?).each { |line| p.print("##{line}\n") }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def deprecation(p, descriptor)
|
|
93
|
+
p.print("# @deprecated\n") if descriptor.options.deprecated?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# rbs_generator.cc's ModulePath: the package's modules as "::A::B"
|
|
97
|
+
def module_path(file)
|
|
98
|
+
convert = true
|
|
99
|
+
if (package = file.options.ruby_package)
|
|
100
|
+
convert = false if package.include?("::")
|
|
101
|
+
else
|
|
102
|
+
package = file.package
|
|
103
|
+
end
|
|
104
|
+
package = package.split(".", -1).map { |part| Naming.package_to_module(part) }.join("::") if convert
|
|
105
|
+
package.empty? ? "" : "::#{package}"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def message_name(message)
|
|
109
|
+
parent = message.containing_message
|
|
110
|
+
prefix = parent ? message_name(parent) : module_path(message.file)
|
|
111
|
+
"#{prefix}::#{Naming.rubify_constant(message.name)}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def enum_name(enum)
|
|
115
|
+
parent = enum.containing_message
|
|
116
|
+
prefix = parent ? message_name(parent) : module_path(enum.file)
|
|
117
|
+
"#{prefix}::#{Naming.rubify_constant(enum.name)}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def scalar_read(field)
|
|
121
|
+
case field.type
|
|
122
|
+
when :double, :float then "::Float"
|
|
123
|
+
when *INTEGERS then "::Integer"
|
|
124
|
+
when :bool then "bool"
|
|
125
|
+
when :string, :bytes then "::String"
|
|
126
|
+
when :enum then "#{enum_name(field.enum_type)}::names | ::Integer"
|
|
127
|
+
when :message, :group then message_name(field.message_type)
|
|
128
|
+
else "untyped"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def scalar_write(field)
|
|
133
|
+
case field.type
|
|
134
|
+
when :double, :float then "::Float | ::Integer"
|
|
135
|
+
when *INTEGERS then "::Integer | ::Float"
|
|
136
|
+
when :bool then "bool"
|
|
137
|
+
when :string then "::String | ::Symbol"
|
|
138
|
+
when :bytes then "::String"
|
|
139
|
+
when :enum
|
|
140
|
+
name = enum_name(field.enum_type)
|
|
141
|
+
"#{name}::names | #{name}::strings | ::Integer | ::Float"
|
|
142
|
+
when :message, :group
|
|
143
|
+
name = message_name(field.message_type)
|
|
144
|
+
case field.message_type.full_name
|
|
145
|
+
when "google.protobuf.Timestamp" then "#{name} | ::Time"
|
|
146
|
+
when "google.protobuf.Duration" then "#{name} | ::int"
|
|
147
|
+
else name
|
|
148
|
+
end
|
|
149
|
+
else "untyped"
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def message?(field)
|
|
154
|
+
field.type == :message || field.type == :group
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def read_type(field)
|
|
158
|
+
if field.map?
|
|
159
|
+
key = field.map_key
|
|
160
|
+
value = field.map_value
|
|
161
|
+
"::Google::Protobuf::Map[#{scalar_read(key)}, #{scalar_read(value)}, #{scalar_write(key)}, " \
|
|
162
|
+
"#{scalar_write(value)}]"
|
|
163
|
+
elsif field.repeated?
|
|
164
|
+
"::Google::Protobuf::RepeatedField[#{scalar_read(field)}, #{scalar_write(field)}]"
|
|
165
|
+
elsif message?(field)
|
|
166
|
+
optional(scalar_read(field))
|
|
167
|
+
else
|
|
168
|
+
scalar_read(field)
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def write_type(field)
|
|
173
|
+
if field.map? || field.repeated?
|
|
174
|
+
read_type(field)
|
|
175
|
+
elsif message?(field) || field.real_oneof
|
|
176
|
+
optional(scalar_write(field))
|
|
177
|
+
else
|
|
178
|
+
scalar_write(field)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def init_type(field)
|
|
183
|
+
if field.map?
|
|
184
|
+
"::Hash[#{scalar_write(field.map_key)}, #{scalar_write(field.map_value)}]?"
|
|
185
|
+
elsif field.repeated?
|
|
186
|
+
"::Array[#{scalar_write(field)}]?"
|
|
187
|
+
elsif message?(field)
|
|
188
|
+
name = message_name(field.message_type)
|
|
189
|
+
optional("#{name} | #{name}::init_map")
|
|
190
|
+
else
|
|
191
|
+
optional(scalar_write(field))
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def enum_value(p, value, path)
|
|
196
|
+
comment(p, path)
|
|
197
|
+
deprecation(p, value)
|
|
198
|
+
name = value.name
|
|
199
|
+
unless name[0].between?("A", "Z")
|
|
200
|
+
if name[0].between?("a", "z")
|
|
201
|
+
name = name[0].upcase + name[1..]
|
|
202
|
+
else
|
|
203
|
+
p.print("# Enum value '#{value.name}' does not start with an uppercase letter as is required for " \
|
|
204
|
+
"Ruby constants.\n# #{value.name}: #{value.number}\n")
|
|
205
|
+
return
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
p.print("#{name}: #{value.number}\n")
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def enum(p, enum, path)
|
|
212
|
+
comment(p, path)
|
|
213
|
+
deprecation(p, enum)
|
|
214
|
+
initial = [true]
|
|
215
|
+
p.print("module #{Naming.rubify_constant(enum.name)}\n")
|
|
216
|
+
p.indent
|
|
217
|
+
mid_line(initial, p)
|
|
218
|
+
p.print("extend ::Google::Protobuf::_EnumModule\n")
|
|
219
|
+
enum.values.each_with_index do |v, i|
|
|
220
|
+
mid_line(initial, p)
|
|
221
|
+
enum_value(p, v, path + [2, i])
|
|
222
|
+
end
|
|
223
|
+
by_number = {}
|
|
224
|
+
enum.values.each { |v| (by_number[v.number] ||= []) << v.name }
|
|
225
|
+
mid_line(initial, p)
|
|
226
|
+
p.print("def self.lookup:\n")
|
|
227
|
+
p.indent
|
|
228
|
+
overload = [true]
|
|
229
|
+
by_number.each do |number, names|
|
|
230
|
+
p.print("#{separator(overload)}(#{number} number) -> #{wrap_union(names.map { |n| ":#{n}" }.join(" | "))}\n")
|
|
231
|
+
end
|
|
232
|
+
p.print("#{separator(overload)}(::int number) -> names?\n")
|
|
233
|
+
p.print("#{separator(overload)}...\n")
|
|
234
|
+
p.outdent
|
|
235
|
+
mid_line(initial, p)
|
|
236
|
+
p.print("def self.resolve:\n")
|
|
237
|
+
p.indent
|
|
238
|
+
overload = [true]
|
|
239
|
+
enum.values.each { |v| p.print("#{separator(overload)}(:#{v.name} name) -> #{v.number}\n") }
|
|
240
|
+
p.print("#{separator(overload)}(::Symbol name) -> numbers?\n")
|
|
241
|
+
p.print("#{separator(overload)}...\n")
|
|
242
|
+
p.outdent
|
|
243
|
+
mid_line(initial, p)
|
|
244
|
+
p.print("type names = #{enum.values.map { |v| ":#{v.name}" }.join(" | ")}\n")
|
|
245
|
+
mid_line(initial, p)
|
|
246
|
+
p.print("type strings = #{enum.values.map { |v| "\"#{v.name}\"" }.join(" | ")}\n")
|
|
247
|
+
mid_line(initial, p)
|
|
248
|
+
p.print("type numbers = #{by_number.keys.join(" | ")}\n")
|
|
249
|
+
p.outdent
|
|
250
|
+
p.print("end\n")
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def field(p, field, path)
|
|
254
|
+
comment(p, path)
|
|
255
|
+
deprecation(p, field)
|
|
256
|
+
read = read_type(field)
|
|
257
|
+
write = write_type(field)
|
|
258
|
+
if read == write
|
|
259
|
+
p.print("attr_accessor #{field.name}(): #{read}\n")
|
|
260
|
+
else
|
|
261
|
+
p.print("attr_reader #{field.name}(): #{read}\nattr_writer #{field.name}(): #{write}\n")
|
|
262
|
+
end
|
|
263
|
+
if !field.repeated? && field.message_type && WRAPPERS.include?(field.message_type.full_name)
|
|
264
|
+
wrapped = field.message_type.fields_by_number[1]
|
|
265
|
+
if wrapped
|
|
266
|
+
wrapped_read = optional(scalar_read(wrapped))
|
|
267
|
+
wrapped_write = optional(scalar_write(wrapped))
|
|
268
|
+
if wrapped_read == wrapped_write
|
|
269
|
+
p.print("attr_accessor #{field.name}_as_value(): #{wrapped_read}\n")
|
|
270
|
+
else
|
|
271
|
+
p.print("attr_reader #{field.name}_as_value(): #{wrapped_read}\n" \
|
|
272
|
+
"attr_writer #{field.name}_as_value(): #{wrapped_write}\n")
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
if field.type == :enum
|
|
277
|
+
if field.repeated?
|
|
278
|
+
p.print("attr_reader #{field.name}_const(): ::Array[::Integer]\n")
|
|
279
|
+
else
|
|
280
|
+
p.print("attr_reader #{field.name}_const(): ::Integer\n")
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
p.print("def has_#{field.name}?: () -> bool\n") if field.presence?
|
|
284
|
+
p.print("def clear_#{field.name}: () -> void\n")
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def oneof(p, oneof, path)
|
|
288
|
+
comment(p, path)
|
|
289
|
+
types = []
|
|
290
|
+
oneof.fields.each do |f|
|
|
291
|
+
t = scalar_read(f)
|
|
292
|
+
types << t unless types.include?(t)
|
|
293
|
+
end
|
|
294
|
+
p.print("attr_reader #{oneof.name}(): #{optional(types.join(" | "))}\n")
|
|
295
|
+
p.print("def has_#{oneof.name}?: () -> bool\n")
|
|
296
|
+
p.print("def clear_#{oneof.name}: () -> void\n")
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def message(p, message, path)
|
|
300
|
+
comment(p, path)
|
|
301
|
+
deprecation(p, message)
|
|
302
|
+
p.print("class #{Naming.rubify_constant(message.name)} < ::Google::Protobuf::AbstractMessage\n")
|
|
303
|
+
p.indent
|
|
304
|
+
initial = [true]
|
|
305
|
+
message.nested_messages.each_with_index do |m, i|
|
|
306
|
+
next if m.map_entry?
|
|
307
|
+
mid_line(initial, p)
|
|
308
|
+
message(p, m, path + [3, i])
|
|
309
|
+
end
|
|
310
|
+
message.nested_enums.each_with_index do |e, i|
|
|
311
|
+
mid_line(initial, p)
|
|
312
|
+
enum(p, e, path + [4, i])
|
|
313
|
+
end
|
|
314
|
+
mid_line(initial, p)
|
|
315
|
+
p.print("include ::Google::Protobuf::_MessageClass[#{message_name(message)}]\n")
|
|
316
|
+
message.fields.each_with_index do |f, i|
|
|
317
|
+
mid_line(initial, p)
|
|
318
|
+
field(p, f, path + [2, i])
|
|
319
|
+
end
|
|
320
|
+
message.oneofs.each_with_index do |o, i|
|
|
321
|
+
mid_line(initial, p)
|
|
322
|
+
oneof(p, o, path + [8, i])
|
|
323
|
+
end
|
|
324
|
+
mid_line(initial, p)
|
|
325
|
+
p.print("type init_map = {\n")
|
|
326
|
+
p.indent
|
|
327
|
+
message.fields.each do |f|
|
|
328
|
+
type = init_type(f)
|
|
329
|
+
p.print("#{f.name}: #{type},\n\"#{f.name}\" => #{type},\n")
|
|
330
|
+
end
|
|
331
|
+
p.outdent
|
|
332
|
+
p.print("}\n")
|
|
333
|
+
mid_line(initial, p)
|
|
334
|
+
p.print("def initialize: (?init_map initial_value) -> void\n")
|
|
335
|
+
full = message.full_name
|
|
336
|
+
if !message.fields.empty? && full != "google.protobuf.ListValue" && full != "google.protobuf.Struct"
|
|
337
|
+
mid_line(initial, p)
|
|
338
|
+
p.print("def []:\n")
|
|
339
|
+
p.indent
|
|
340
|
+
overload = [true]
|
|
341
|
+
message.fields.each do |f|
|
|
342
|
+
p.print("#{separator(overload)}(\"#{f.name}\" name) -> #{wrap_union(read_type(f))}\n")
|
|
343
|
+
end
|
|
344
|
+
p.outdent
|
|
345
|
+
mid_line(initial, p)
|
|
346
|
+
p.print("def []=:\n")
|
|
347
|
+
p.indent
|
|
348
|
+
overload = [true]
|
|
349
|
+
message.fields.each do |f|
|
|
350
|
+
p.print("#{separator(overload)}(\"#{f.name}\" name, #{wrap_union(write_type(f))} value) -> void\n")
|
|
351
|
+
end
|
|
352
|
+
p.outdent
|
|
353
|
+
end
|
|
354
|
+
p.outdent
|
|
355
|
+
p.print("end\n")
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def message_lookup(p, message, overload)
|
|
359
|
+
p.print("#{separator(overload)}(\"#{message.full_name}\" name) -> (::Google::Protobuf::Descriptor & " \
|
|
360
|
+
"::Google::Protobuf::_SpecificDescriptor[singleton(#{message_name(message)})])\n")
|
|
361
|
+
message.nested_messages.each { |m| message_lookup(p, m, overload) unless m.map_entry? }
|
|
362
|
+
message.nested_enums.each { |e| enum_lookup(p, e, overload) }
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def enum_lookup(p, enum, overload)
|
|
366
|
+
p.print("#{separator(overload)}(\"#{enum.full_name}\" name) -> (::Google::Protobuf::EnumDescriptor & " \
|
|
367
|
+
"::Google::Protobuf::_SpecificEnumDescriptor[singleton(#{enum_name(enum)})])\n")
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def lookup_override(p, file)
|
|
371
|
+
p.print("module Google\n")
|
|
372
|
+
p.indent
|
|
373
|
+
p.print("module Protobuf\n")
|
|
374
|
+
p.indent
|
|
375
|
+
p.print("class DescriptorPool\n")
|
|
376
|
+
p.indent
|
|
377
|
+
p.print("def lookup:\n")
|
|
378
|
+
p.indent
|
|
379
|
+
overload = [true]
|
|
380
|
+
file.messages.each { |m| message_lookup(p, m, overload) }
|
|
381
|
+
file.enums.each { |e| enum_lookup(p, e, overload) }
|
|
382
|
+
p.print("#{separator(overload)}...\n")
|
|
383
|
+
p.outdent
|
|
384
|
+
p.outdent
|
|
385
|
+
p.print("end\n")
|
|
386
|
+
p.outdent
|
|
387
|
+
p.print("end\n")
|
|
388
|
+
p.outdent
|
|
389
|
+
p.print("end\n")
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|