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,340 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
class Compiler
|
|
5
|
+
# Just enough of protoc's text-format parser to read aggregate option
|
|
6
|
+
# values (`option (opt) = { a: 1 b { c: "x" } [ext]: 2 };`) into option
|
|
7
|
+
# entries, with protoc's error messages for the common mistakes.
|
|
8
|
+
#
|
|
9
|
+
# @api private
|
|
10
|
+
class TextFormat
|
|
11
|
+
ANY_PREFIXES = ["type.googleapis.com/", "type.googleprod.com/"].freeze
|
|
12
|
+
INT32_MAX = 2**31 - 1
|
|
13
|
+
INT64_MAX = 2**63 - 1
|
|
14
|
+
UINT32_MAX = 2**32 - 1
|
|
15
|
+
UINT64_MAX = 2**64 - 1
|
|
16
|
+
RECURSION_LIMIT = 100
|
|
17
|
+
|
|
18
|
+
# @return [Array<String>]
|
|
19
|
+
attr_reader :errors
|
|
20
|
+
|
|
21
|
+
# @param text [String] the aggregate value, braces excluded
|
|
22
|
+
# @param type [Schema::Message]
|
|
23
|
+
# @param interpreter [OptionInterpreter] maps symbols to descriptors
|
|
24
|
+
# @param table [SymbolTable] resolves `[extension]` names
|
|
25
|
+
def initialize(text, type, interpreter, table)
|
|
26
|
+
@type = type
|
|
27
|
+
@interpreter = interpreter
|
|
28
|
+
@table = table
|
|
29
|
+
@errors = []
|
|
30
|
+
@lexer = Lexer.new(text, ->(_line, _column, message) { @errors << message })
|
|
31
|
+
@lexer.next
|
|
32
|
+
@depth = RECURSION_LIMIT
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [Array, nil] the entries, or nil after errors
|
|
36
|
+
def parse
|
|
37
|
+
entries = []
|
|
38
|
+
until looking_at_type?(:end)
|
|
39
|
+
return nil unless consume_field(@type, entries)
|
|
40
|
+
end
|
|
41
|
+
@errors.empty? ? entries : nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def looking_at?(text)
|
|
47
|
+
@lexer.current.text == text
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def looking_at_type?(type)
|
|
51
|
+
@lexer.current.type == type
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def try_consume(text)
|
|
55
|
+
return false unless looking_at?(text)
|
|
56
|
+
@lexer.next
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def consume(text)
|
|
61
|
+
return true if try_consume(text)
|
|
62
|
+
error("Expected \"#{text}\", found \"#{@lexer.current.text}\".")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def error(message)
|
|
66
|
+
@errors << message
|
|
67
|
+
false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def consume_message(type, delimiter, entries)
|
|
71
|
+
@depth -= 1
|
|
72
|
+
return error("Message is too deep, the parser exceeded the configured recursion limit of #{RECURSION_LIMIT}.") if @depth < 0
|
|
73
|
+
until looking_at?(">") || looking_at?("}")
|
|
74
|
+
return false unless consume_field(type, entries)
|
|
75
|
+
end
|
|
76
|
+
consume(delimiter)
|
|
77
|
+
ensure
|
|
78
|
+
@depth += 1
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def message_delimiter
|
|
82
|
+
return ">" if try_consume("<")
|
|
83
|
+
consume("{") ? "}" : nil
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# The text between brackets, URL characters included
|
|
87
|
+
def bracketed_name
|
|
88
|
+
consume("[")
|
|
89
|
+
name = +""
|
|
90
|
+
until looking_at?("]") || looking_at_type?(:end)
|
|
91
|
+
name << @lexer.current.text
|
|
92
|
+
@lexer.next
|
|
93
|
+
end
|
|
94
|
+
return nil unless consume("]")
|
|
95
|
+
name
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def consume_field(type, entries)
|
|
99
|
+
if type.full_name == "google.protobuf.Any" && looking_at?("[")
|
|
100
|
+
return consume_any(type, entries)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if looking_at?("[")
|
|
104
|
+
name = bracketed_name
|
|
105
|
+
return false unless name
|
|
106
|
+
return error("Extension name contains \"/\"") if name.include?("/")
|
|
107
|
+
field = find_extension(type, name)
|
|
108
|
+
unless field
|
|
109
|
+
return error("Extension \"#{name}\" is not defined or is not an extension of \"#{type.full_name}\".")
|
|
110
|
+
end
|
|
111
|
+
else
|
|
112
|
+
unless looking_at_type?(:identifier)
|
|
113
|
+
return error("Expected identifier, got: #{@lexer.current.text}")
|
|
114
|
+
end
|
|
115
|
+
name = @lexer.current.text.dup.force_encoding(Encoding::UTF_8)
|
|
116
|
+
@lexer.next
|
|
117
|
+
field = type.fields_by_name[name]
|
|
118
|
+
if field.nil?
|
|
119
|
+
lower = type.fields_by_name[name.downcase]
|
|
120
|
+
field = lower if lower && group_like?(lower) && lower.message_type.name == name
|
|
121
|
+
end
|
|
122
|
+
return error("Message type \"#{type.full_name}\" has no field named \"#{name}\".") unless field
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if !field.repeated? && entries.any? { |f, _| f.equal?(field) }
|
|
126
|
+
return error("Non-repeated field \"#{name}\" is specified multiple times.")
|
|
127
|
+
end
|
|
128
|
+
if (oneof = field.real_oneof) && (other = entries.find { |f, _| f.real_oneof.equal?(oneof) })
|
|
129
|
+
return error("Field \"#{name}\" is specified along with field \"#{other[0].name}\", another member of " \
|
|
130
|
+
"oneof \"#{oneof.name}\".")
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
message = field.type == :message || field.type == :group
|
|
134
|
+
if message
|
|
135
|
+
try_consume(":")
|
|
136
|
+
else
|
|
137
|
+
return false unless consume(":")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
if field.repeated? && try_consume("[")
|
|
141
|
+
unless try_consume("]")
|
|
142
|
+
loop do
|
|
143
|
+
value = message ? field_message(field) : field_value(field)
|
|
144
|
+
return false if value.nil?
|
|
145
|
+
entries << [field, value]
|
|
146
|
+
break if try_consume("]")
|
|
147
|
+
return false unless consume(",")
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
else
|
|
151
|
+
value = message ? field_message(field) : field_value(field)
|
|
152
|
+
return false if value.nil?
|
|
153
|
+
entries << [field, value]
|
|
154
|
+
end
|
|
155
|
+
try_consume(";") || try_consume(",")
|
|
156
|
+
true
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def group_like?(field)
|
|
160
|
+
return false unless field.type == :group
|
|
161
|
+
return false unless field.name == field.message_type.name.downcase
|
|
162
|
+
return false unless field.message_type.file.equal?(field.file)
|
|
163
|
+
field.message_type.containing_message.equal?(field.containing_message)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def find_extension(type, name)
|
|
167
|
+
symbol = @table.lookup(name, type.full_name)
|
|
168
|
+
if symbol&.kind == :field
|
|
169
|
+
field = @interpreter.schema_of(symbol)
|
|
170
|
+
return field if field.extension? && field.extendee.full_name == type.full_name
|
|
171
|
+
return nil
|
|
172
|
+
end
|
|
173
|
+
if symbol&.kind == :message && type.message_set_wire_format?
|
|
174
|
+
foreign = @interpreter.schema_of(symbol)
|
|
175
|
+
return foreign.extensions.find do |ext|
|
|
176
|
+
ext.extendee.full_name == type.full_name && ext.type == :message && ext.label == :optional &&
|
|
177
|
+
ext.message_type.equal?(foreign)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
nil
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def field_message(field)
|
|
184
|
+
delimiter = message_delimiter
|
|
185
|
+
return nil unless delimiter
|
|
186
|
+
entries = []
|
|
187
|
+
return nil unless consume_message(field.message_type, delimiter, entries)
|
|
188
|
+
entries
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def consume_any(type, entries)
|
|
192
|
+
text = bracketed_name
|
|
193
|
+
return false unless text
|
|
194
|
+
slash = text.rindex("/")
|
|
195
|
+
return error("Type URL prefix is missing") unless slash
|
|
196
|
+
prefix = text[0..slash]
|
|
197
|
+
full_name = text[(slash + 1)..]
|
|
198
|
+
try_consume(":")
|
|
199
|
+
target = nil
|
|
200
|
+
if ANY_PREFIXES.include?(prefix)
|
|
201
|
+
symbol = @table.find(full_name)
|
|
202
|
+
target = @interpreter.schema_of(symbol) if symbol&.kind == :message
|
|
203
|
+
end
|
|
204
|
+
return error("Could not find type \"#{text}\" stored in google.protobuf.Any.") unless target
|
|
205
|
+
delimiter = message_delimiter
|
|
206
|
+
return false unless delimiter
|
|
207
|
+
inner = []
|
|
208
|
+
return false unless consume_message(target, delimiter, inner)
|
|
209
|
+
if entries.any? { |f, _| f.number == 1 || f.number == 2 }
|
|
210
|
+
return error("Non-repeated Any specified multiple times.")
|
|
211
|
+
end
|
|
212
|
+
entries << [type.field(1), text]
|
|
213
|
+
entries << [type.field(2), @interpreter.fold(inner).encode(target)]
|
|
214
|
+
try_consume(";") || try_consume(",")
|
|
215
|
+
true
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def field_value(field)
|
|
219
|
+
case field.type
|
|
220
|
+
when :int32, :sint32, :sfixed32 then signed_integer(INT32_MAX)
|
|
221
|
+
when :int64, :sint64, :sfixed64 then signed_integer(INT64_MAX)
|
|
222
|
+
when :uint32, :fixed32 then unsigned_integer(UINT32_MAX)
|
|
223
|
+
when :uint64, :fixed64 then unsigned_integer(UINT64_MAX)
|
|
224
|
+
when :float
|
|
225
|
+
v = double
|
|
226
|
+
v.nil? ? nil : Schema::DefaultValue.to_float32(v)
|
|
227
|
+
when :double then double
|
|
228
|
+
when :string, :bytes
|
|
229
|
+
unless looking_at_type?(:string)
|
|
230
|
+
error("Expected string, got: #{@lexer.current.text}")
|
|
231
|
+
return nil
|
|
232
|
+
end
|
|
233
|
+
out = "".b
|
|
234
|
+
while looking_at_type?(:string)
|
|
235
|
+
Lexer.parse_string(@lexer.current.text, out)
|
|
236
|
+
@lexer.next
|
|
237
|
+
end
|
|
238
|
+
(field.type == :string) ? out.force_encoding(Encoding::UTF_8) : out
|
|
239
|
+
when :bool
|
|
240
|
+
if looking_at_type?(:integer)
|
|
241
|
+
v = unsigned_integer(1)
|
|
242
|
+
return v.nil? ? nil : v == 1
|
|
243
|
+
end
|
|
244
|
+
unless looking_at_type?(:identifier)
|
|
245
|
+
error("Expected identifier, got: #{@lexer.current.text}")
|
|
246
|
+
return nil
|
|
247
|
+
end
|
|
248
|
+
text = @lexer.current.text
|
|
249
|
+
@lexer.next
|
|
250
|
+
case text
|
|
251
|
+
when "true", "True", "t" then true
|
|
252
|
+
when "false", "False", "f" then false
|
|
253
|
+
else
|
|
254
|
+
error("Invalid value for boolean field \"#{field.name}\". Value: \"#{text}\".")
|
|
255
|
+
nil
|
|
256
|
+
end
|
|
257
|
+
when :enum then enum_value(field)
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def enum_value(field)
|
|
262
|
+
enum = field.enum_type
|
|
263
|
+
if looking_at_type?(:identifier)
|
|
264
|
+
text = @lexer.current.text
|
|
265
|
+
@lexer.next
|
|
266
|
+
value = enum.values_by_name[text]
|
|
267
|
+
elsif looking_at?("-") || looking_at_type?(:integer)
|
|
268
|
+
number = signed_integer(INT32_MAX)
|
|
269
|
+
return nil if number.nil?
|
|
270
|
+
text = number.to_s
|
|
271
|
+
value = enum.value(number)
|
|
272
|
+
return number if value.nil? && !enum.closed?
|
|
273
|
+
else
|
|
274
|
+
error("Expected integer or identifier, got: #{@lexer.current.text}")
|
|
275
|
+
return nil
|
|
276
|
+
end
|
|
277
|
+
unless value
|
|
278
|
+
error("Unknown enumeration value of \"#{text}\" for field \"#{field.name}\".")
|
|
279
|
+
return nil
|
|
280
|
+
end
|
|
281
|
+
enum.values_by_number.fetch(value.number).name.to_sym
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def unsigned_integer(max)
|
|
285
|
+
unless looking_at_type?(:integer)
|
|
286
|
+
error("Expected integer, got: #{@lexer.current.text}")
|
|
287
|
+
return nil
|
|
288
|
+
end
|
|
289
|
+
value = Lexer.parse_integer(@lexer.current.text, max)
|
|
290
|
+
unless value
|
|
291
|
+
error("Integer out of range (#{@lexer.current.text})")
|
|
292
|
+
return nil
|
|
293
|
+
end
|
|
294
|
+
@lexer.next
|
|
295
|
+
value
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def signed_integer(max)
|
|
299
|
+
negative = try_consume("-")
|
|
300
|
+
value = unsigned_integer(negative ? max + 1 : max)
|
|
301
|
+
return nil if value.nil?
|
|
302
|
+
negative ? -value : value
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def double
|
|
306
|
+
negative = try_consume("-")
|
|
307
|
+
token = @lexer.current
|
|
308
|
+
value = case token.type
|
|
309
|
+
when :integer
|
|
310
|
+
if token.text.match?(/\A0[xX]/) || token.text.match?(/\A0\d/)
|
|
311
|
+
error("Expect a decimal number, got: #{token.text}")
|
|
312
|
+
return nil
|
|
313
|
+
end
|
|
314
|
+
int = Lexer.parse_integer(token.text, UINT64_MAX)
|
|
315
|
+
@lexer.next
|
|
316
|
+
int ? int.to_f : Lexer.parse_float(token.text)
|
|
317
|
+
when :float
|
|
318
|
+
@lexer.next
|
|
319
|
+
Lexer.parse_float(token.text)
|
|
320
|
+
when :identifier
|
|
321
|
+
text = token.text.downcase
|
|
322
|
+
if text == "inf" || text == "infinity"
|
|
323
|
+
@lexer.next
|
|
324
|
+
Float::INFINITY
|
|
325
|
+
elsif text == "nan"
|
|
326
|
+
@lexer.next
|
|
327
|
+
Float::NAN
|
|
328
|
+
else
|
|
329
|
+
error("Expected double, got: #{text}")
|
|
330
|
+
return nil
|
|
331
|
+
end
|
|
332
|
+
else
|
|
333
|
+
error("Expected double, got: #{token.text}")
|
|
334
|
+
return nil
|
|
335
|
+
end
|
|
336
|
+
negative ? -value : value
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|