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,367 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
# The runtime of generated `_pb.rb` files, also meant to be written by hand.
|
|
5
|
+
# A block describes one `.proto` file through {Schema::File.draft}; the
|
|
6
|
+
# file is resolved and frozen into {Protostar.generated_pool}, and its
|
|
7
|
+
# message classes and enum modules are defined.
|
|
8
|
+
#
|
|
9
|
+
# Protostar::DSL.file("acme/person.proto", package: "acme", syntax: :proto3) do |f|
|
|
10
|
+
# f.message "Person" do |m|
|
|
11
|
+
# m.field :name, 1, :string
|
|
12
|
+
# m.field :friends, 2, :message, ".acme.Person", label: :repeated
|
|
13
|
+
# m.oneof :contact do |o|
|
|
14
|
+
# o.field :email, 3, :string
|
|
15
|
+
# end
|
|
16
|
+
# m.map :attrs, 4, :string, :string
|
|
17
|
+
# end
|
|
18
|
+
# end
|
|
19
|
+
# module Acme
|
|
20
|
+
# Person = Protostar::DSL.message("acme.Person")
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# Every descriptor-level call takes the options of its descriptor as extra
|
|
24
|
+
# keywords: `deprecated: true`, `packed: false`, `features: {...}`, with
|
|
25
|
+
# custom options by extension full name under `extensions:` and fields
|
|
26
|
+
# nobody could interpret as wire bytes under `unknown_fields:`. An
|
|
27
|
+
# `options:` Hash is taken as the options message verbatim instead, in the
|
|
28
|
+
# same spelling, and is how an empty options message is written. Option
|
|
29
|
+
# values that are messages are Hashes in that spelling too; a field of
|
|
30
|
+
# such a message that is itself named `extensions` or `unknown_fields` is
|
|
31
|
+
# given with a String key.
|
|
32
|
+
#
|
|
33
|
+
# The earlier spellings, `__extensions:`, `__unknown_fields:` (as
|
|
34
|
+
# `[number, wire_type, bytes]` triples) and `visibility: :VISIBILITY_EXPORT`,
|
|
35
|
+
# are still read until 0.2.0, with a deprecation warning.
|
|
36
|
+
module DSL
|
|
37
|
+
# Raised for a call the DSL cannot turn into a descriptor
|
|
38
|
+
class Error < Protostar::Error; end
|
|
39
|
+
|
|
40
|
+
SYNTAXES = {proto2: :proto2, proto3: :proto3, editions: :editions}.freeze
|
|
41
|
+
LABELS = %i[optional required repeated].freeze
|
|
42
|
+
OLD_VISIBILITIES = {VISIBILITY_LOCAL: :local, VISIBILITY_EXPORT: :export}.freeze
|
|
43
|
+
|
|
44
|
+
class << self
|
|
45
|
+
# Describes, builds and defines one `.proto` file. Loading a file the pool
|
|
46
|
+
# already has is a no-op that returns the file there.
|
|
47
|
+
#
|
|
48
|
+
# @param name [String] the file name as imported, e.g. "acme/person.proto"
|
|
49
|
+
# @param package [String, nil]
|
|
50
|
+
# @param syntax [Symbol, String, nil] :proto2, :proto3 or :editions; omitted for proto2 as protoc does
|
|
51
|
+
# @param edition [Symbol, Integer, nil] e.g. :EDITION_2023 or 2023; implies `syntax: :editions`
|
|
52
|
+
# @param dependencies [Array<String>] imported file names, which must be loaded already
|
|
53
|
+
# @param public_dependencies [Array<String, Integer>] names (or indexes) of `import public` files
|
|
54
|
+
# @param weak_dependencies [Array<String, Integer>]
|
|
55
|
+
# @param option_dependencies [Array<String>] `import option` file names
|
|
56
|
+
# @param options [Hash, nil] the FileOptions verbatim
|
|
57
|
+
# @param pool [Schema::Pool] where the file is built and added
|
|
58
|
+
# @param registry [Types::Registry, nil] where classes are defined; nil builds the file only
|
|
59
|
+
# @param file_options [Hash] FileOptions fields as keywords, custom ones under `extensions:`
|
|
60
|
+
# @yieldparam f [FileBuilder]
|
|
61
|
+
# @return [Schema::File]
|
|
62
|
+
def file(name, package: nil, syntax: nil, edition: nil, dependencies: nil, public_dependencies: nil,
|
|
63
|
+
weak_dependencies: nil, option_dependencies: nil, options: nil, pool: Protostar.generated_pool,
|
|
64
|
+
registry: Types.registry, **file_options, &block)
|
|
65
|
+
existing = pool.file(name)
|
|
66
|
+
return existing if existing
|
|
67
|
+
draft = begin
|
|
68
|
+
Schema::File.draft(name, package: package, syntax: syntax(name, syntax), edition: edition(edition),
|
|
69
|
+
dependencies: Array(dependencies), public_dependencies: Array(public_dependencies),
|
|
70
|
+
weak_dependencies: Array(weak_dependencies), option_dependencies: Array(option_dependencies),
|
|
71
|
+
options: DSL.options(options, file_options))
|
|
72
|
+
rescue Schema::Error => e
|
|
73
|
+
raise Error, e.message
|
|
74
|
+
end
|
|
75
|
+
block&.call(FileBuilder.new(draft))
|
|
76
|
+
built = draft.resolve(pool).freeze!
|
|
77
|
+
pool.add(built)
|
|
78
|
+
registry&.define(built)
|
|
79
|
+
built
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @param full_name [String] e.g. "acme.Person"
|
|
83
|
+
# @return [Class] the message class defined for it
|
|
84
|
+
# @raise [Error] when no file defined it
|
|
85
|
+
def message(full_name, registry: Types.registry)
|
|
86
|
+
found = registry.find(full_name)
|
|
87
|
+
raise Error, "no message #{full_name} has been defined" unless found.is_a?(Class)
|
|
88
|
+
found
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @param full_name [String]
|
|
92
|
+
# @return [Module] the enum module defined for it
|
|
93
|
+
def enum(full_name, registry: Types.registry)
|
|
94
|
+
found = registry.find(full_name)
|
|
95
|
+
raise Error, "no enum #{full_name} has been defined" unless found.is_a?(Module) && !found.is_a?(Class)
|
|
96
|
+
found
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# A Module standing for a service, which gRPC stubs reopen to add
|
|
100
|
+
# `Service` and `Stub`
|
|
101
|
+
# @param full_name [String]
|
|
102
|
+
# @return [Module] answering `descriptor` with the {Schema::Service}
|
|
103
|
+
def service(full_name, pool: Protostar.generated_pool)
|
|
104
|
+
descriptor = pool.find_service(full_name) || raise(Error, "no service #{full_name} has been defined")
|
|
105
|
+
mod = Module.new
|
|
106
|
+
mod.instance_variable_set(:@descriptor, descriptor)
|
|
107
|
+
mod.extend(ServiceModule)
|
|
108
|
+
mod
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Options given as keywords merged into a verbatim options Hash
|
|
112
|
+
# @api private
|
|
113
|
+
def options(verbatim, keywords)
|
|
114
|
+
return verbatim if keywords.empty?
|
|
115
|
+
out = verbatim ? verbatim.dup : {}
|
|
116
|
+
keywords.each do |key, value|
|
|
117
|
+
if key == :extensions
|
|
118
|
+
out[:extensions] = (out[:extensions] || {}).merge(value)
|
|
119
|
+
else
|
|
120
|
+
out[key] = value
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
out
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# :local or :export; the deprecated protoc spellings are read with a warning
|
|
127
|
+
# @api private
|
|
128
|
+
def visibility(value)
|
|
129
|
+
replacement = OLD_VISIBILITIES[value]
|
|
130
|
+
return value unless replacement
|
|
131
|
+
Protostar.deprecated("visibility: #{value.inspect}", "visibility: #{replacement.inspect}")
|
|
132
|
+
replacement
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# protoc's name for the entry message of a map field
|
|
136
|
+
# @param field_name [String]
|
|
137
|
+
# @return [String]
|
|
138
|
+
def map_entry_name(field_name)
|
|
139
|
+
Schema::Draft.map_entry_name(field_name)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# A field type as the draft spells it: a short type Symbol, or a type name
|
|
143
|
+
# @api private
|
|
144
|
+
def type(type)
|
|
145
|
+
return type if type.is_a?(String)
|
|
146
|
+
type = type.to_sym
|
|
147
|
+
type = Schema::Field::TYPES.fetch(type, type)
|
|
148
|
+
raise Error, "unknown field type #{type.inspect}" unless Schema::Field::TYPES.value?(type)
|
|
149
|
+
type
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# @api private
|
|
153
|
+
def label(label)
|
|
154
|
+
return :optional if label.nil?
|
|
155
|
+
label = label.to_sym
|
|
156
|
+
label = Schema::Field::LABELS.fetch(label, label)
|
|
157
|
+
raise Error, "unknown label #{label.inspect}" unless LABELS.include?(label)
|
|
158
|
+
label
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
private
|
|
162
|
+
|
|
163
|
+
def syntax(name, syntax)
|
|
164
|
+
return nil if syntax.nil?
|
|
165
|
+
SYNTAXES.fetch(syntax.to_sym) { raise Error, "#{name}: unknown syntax #{syntax.inspect}" }
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def edition(edition)
|
|
169
|
+
return edition unless edition.is_a?(Integer)
|
|
170
|
+
Schema::Features::EDITION_NAMES.fetch(edition) { :"EDITION_#{edition}" }
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Extended by the Modules {DSL.service} returns
|
|
175
|
+
module ServiceModule
|
|
176
|
+
# @return [Schema::Service]
|
|
177
|
+
attr_reader :descriptor
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Common to every scope that holds messages, enums and extensions
|
|
181
|
+
# @api private
|
|
182
|
+
class Scope
|
|
183
|
+
def initialize(draft)
|
|
184
|
+
@draft = draft
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# A nested (or top-level) message
|
|
188
|
+
# @param name [String]
|
|
189
|
+
# @param visibility [Symbol, nil] :local or :export (edition 2024)
|
|
190
|
+
# @param options [Hash, nil] MessageOptions verbatim
|
|
191
|
+
# @yieldparam m [MessageBuilder]
|
|
192
|
+
def message(name, visibility: nil, options: nil, **message_options, &block)
|
|
193
|
+
visibility = DSL.visibility(visibility)
|
|
194
|
+
@draft.message(name, visibility: visibility, options: DSL.options(options, message_options)) do |m|
|
|
195
|
+
block&.call(MessageBuilder.new(m))
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# An enum
|
|
200
|
+
# @yieldparam e [EnumBuilder]
|
|
201
|
+
def enum(name, visibility: nil, options: nil, **enum_options, &block)
|
|
202
|
+
visibility = DSL.visibility(visibility)
|
|
203
|
+
@draft.enum(name, visibility: visibility, options: DSL.options(options, enum_options)) do |e|
|
|
204
|
+
block&.call(EnumBuilder.new(e))
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Extensions of another message declared in this scope
|
|
209
|
+
# @param extendee [String] the extended message, e.g. ".acme.Base"
|
|
210
|
+
# @yieldparam e [ExtendBuilder]
|
|
211
|
+
def extend(extendee, &block)
|
|
212
|
+
block.call(ExtendBuilder.new(@draft, extendee.to_s))
|
|
213
|
+
self
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# The block argument of {DSL.file}
|
|
218
|
+
class FileBuilder < Scope
|
|
219
|
+
# @param name [String]
|
|
220
|
+
# @yieldparam s [ServiceBuilder]
|
|
221
|
+
def service(name, options: nil, **service_options, &block)
|
|
222
|
+
@draft.service(name, options: DSL.options(options, service_options)) do |s|
|
|
223
|
+
block&.call(ServiceBuilder.new(s))
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# The block argument of {Scope#message}
|
|
229
|
+
class MessageBuilder < Scope
|
|
230
|
+
# A field
|
|
231
|
+
# @param name [Symbol, String]
|
|
232
|
+
# @param number [Integer]
|
|
233
|
+
# @param type [Symbol, String] :int32, :string, :message, :enum, :group, ...; a String is taken as
|
|
234
|
+
# the type name of a message or enum, its kind looked up when the file is built
|
|
235
|
+
# @param type_name [String, nil] the message or enum type, e.g. ".acme.Person"
|
|
236
|
+
# @param label [Symbol, nil] :optional (the default), :required or :repeated
|
|
237
|
+
# @param default [Object, nil] the default as protoc stores it: text, C-escaped for bytes
|
|
238
|
+
# @param json_name [String, nil] when not the one derived from the name
|
|
239
|
+
# @param proto3_optional [Boolean] a proto3 `optional` field; its synthetic oneof is made for it
|
|
240
|
+
# @param oneof [Symbol, String, nil] the oneof the field belongs to
|
|
241
|
+
# @param options [Hash, nil] FieldOptions verbatim
|
|
242
|
+
def field(name, number, type, type_name = nil, label: nil, default: nil, json_name: nil, proto3_optional: nil,
|
|
243
|
+
oneof: nil, options: nil, **field_options)
|
|
244
|
+
@draft.field(name, number, DSL.type(type), type_name, label: DSL.label(label), default: default,
|
|
245
|
+
json_name: json_name, optional: proto3_optional ? true : false, oneof: oneof,
|
|
246
|
+
options: DSL.options(options, field_options))
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# A `map<K, V>` field and its synthesized entry message
|
|
250
|
+
# @param key_type [Symbol]
|
|
251
|
+
# @param value_type [Symbol, String] a scalar type, :message or :enum (then give `value_type_name`),
|
|
252
|
+
# or the value's type name
|
|
253
|
+
def map(name, number, key_type, value_type, value_type_name = nil, json_name: nil, options: nil, **field_options)
|
|
254
|
+
value = value_type.is_a?(String) ? value_type : DSL.type(value_type)
|
|
255
|
+
@draft.map(name, number, key: DSL.type(key_type), value: value, value_type_name: value_type_name,
|
|
256
|
+
json_name: json_name, options: DSL.options(options, field_options))
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# A proto2 group: a field of type group and its nested message, named as
|
|
260
|
+
# in `group Name = number { ... }`
|
|
261
|
+
# @yieldparam g [MessageBuilder]
|
|
262
|
+
def group(name, number, label: nil, json_name: nil, oneof: nil, options: nil, message_options: nil,
|
|
263
|
+
**field_options, &block)
|
|
264
|
+
@draft.group(name, number, label: DSL.label(label), json_name: json_name, oneof: oneof,
|
|
265
|
+
options: DSL.options(options, field_options), message_options: message_options) do |g|
|
|
266
|
+
block&.call(MessageBuilder.new(g))
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# A oneof. Fields given in the block belong to it; fields elsewhere may
|
|
271
|
+
# name it with `oneof:`.
|
|
272
|
+
# @yieldparam o [OneofBuilder]
|
|
273
|
+
def oneof(name, options: nil, **oneof_options, &block)
|
|
274
|
+
@draft.oneof(name.to_s, options: DSL.options(options, oneof_options))
|
|
275
|
+
block&.call(OneofBuilder.new(self, name))
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
# Extension ranges, inclusive
|
|
279
|
+
# @param ranges [Array<Range, Integer>]
|
|
280
|
+
def extensions(*ranges, options: nil, **range_options)
|
|
281
|
+
@draft.extensions(*ranges, options: DSL.options(options, range_options))
|
|
282
|
+
self
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Reserved numbers (Integers or inclusive Ranges) and names (Strings)
|
|
286
|
+
def reserved(*items)
|
|
287
|
+
@draft.reserved(*items)
|
|
288
|
+
self
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# The block argument of {MessageBuilder#oneof}
|
|
293
|
+
class OneofBuilder
|
|
294
|
+
# @api private
|
|
295
|
+
def initialize(message, name)
|
|
296
|
+
@message = message
|
|
297
|
+
@name = name
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# A member field; same arguments as {MessageBuilder#field}
|
|
301
|
+
def field(name, number, type, type_name = nil, **kwargs)
|
|
302
|
+
@message.field(name, number, type, type_name, oneof: @name, **kwargs)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# A member group; same arguments as {MessageBuilder#group}
|
|
306
|
+
def group(name, number, **kwargs, &block)
|
|
307
|
+
@message.group(name, number, oneof: @name, **kwargs, &block)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# The block argument of {Scope#extend}
|
|
312
|
+
class ExtendBuilder
|
|
313
|
+
# @api private
|
|
314
|
+
def initialize(draft, extendee)
|
|
315
|
+
@draft = draft
|
|
316
|
+
@extendee = extendee
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# An extension field; same arguments as {MessageBuilder#field}
|
|
320
|
+
def field(name, number, type, type_name = nil, label: nil, default: nil, json_name: nil, proto3_optional: nil,
|
|
321
|
+
options: nil, **field_options)
|
|
322
|
+
@draft.extension(name, number, DSL.type(type), type_name, extendee: @extendee, label: DSL.label(label),
|
|
323
|
+
default: default, json_name: json_name, optional: proto3_optional ? true : false,
|
|
324
|
+
options: DSL.options(options, field_options))
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# The block argument of {Scope#enum}
|
|
329
|
+
class EnumBuilder
|
|
330
|
+
# @api private
|
|
331
|
+
def initialize(draft)
|
|
332
|
+
@draft = draft
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# @param name [Symbol, String]
|
|
336
|
+
# @param number [Integer]
|
|
337
|
+
def value(name, number, options: nil, **value_options)
|
|
338
|
+
@draft.value(name, number, options: DSL.options(options, value_options))
|
|
339
|
+
self
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# Reserved numbers (Integers or inclusive Ranges) and names (Strings)
|
|
343
|
+
def reserved(*items)
|
|
344
|
+
@draft.reserved(*items)
|
|
345
|
+
self
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# The block argument of {FileBuilder#service}
|
|
350
|
+
class ServiceBuilder
|
|
351
|
+
# @api private
|
|
352
|
+
def initialize(draft)
|
|
353
|
+
@draft = draft
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# @param name [Symbol, String]
|
|
357
|
+
# @param input_type [String] e.g. ".acme.Request"
|
|
358
|
+
# @param output_type [String]
|
|
359
|
+
def rpc(name, input_type, output_type, client_streaming: false, server_streaming: false, options: nil,
|
|
360
|
+
**method_options)
|
|
361
|
+
@draft.rpc(name, input_type, output_type, client_streaming: client_streaming,
|
|
362
|
+
server_streaming: server_streaming, options: DSL.options(options, method_options))
|
|
363
|
+
self
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
# Extended by every enum Module that {Types.define} makes. Such a Module has
|
|
5
|
+
# one constant per value (aliases included) holding its number, and is frozen.
|
|
6
|
+
#
|
|
7
|
+
# Color::RED # => 1
|
|
8
|
+
# Color.lookup(1) # => :RED
|
|
9
|
+
# Color.resolve(:RED) # => 1
|
|
10
|
+
module Enum
|
|
11
|
+
# @return [Schema::Enum]
|
|
12
|
+
attr_reader :descriptor
|
|
13
|
+
|
|
14
|
+
# @param number [Integer]
|
|
15
|
+
# @return [Symbol, nil] the first name declared for the number
|
|
16
|
+
def lookup(number)
|
|
17
|
+
@__names[number]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @param name [Symbol, String]
|
|
21
|
+
# @return [Integer, nil]
|
|
22
|
+
def resolve(name)
|
|
23
|
+
@__numbers[name.is_a?(String) ? name.to_sym : name]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def __names
|
|
28
|
+
@__names
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @api private
|
|
32
|
+
def __numbers
|
|
33
|
+
@__numbers
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def inspect
|
|
37
|
+
name || "#<Module #{@descriptor.full_name}>"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Builds the enum Module for a descriptor
|
|
41
|
+
# @param descriptor [Schema::Enum]
|
|
42
|
+
# @return [Module] frozen
|
|
43
|
+
# @api private
|
|
44
|
+
def self.build(descriptor)
|
|
45
|
+
mod = Module.new
|
|
46
|
+
mod.extend(self)
|
|
47
|
+
names = {}
|
|
48
|
+
numbers = {}
|
|
49
|
+
descriptor.values.each do |v|
|
|
50
|
+
sym = v.name.to_sym
|
|
51
|
+
names[v.number] ||= sym
|
|
52
|
+
numbers[sym] = v.number
|
|
53
|
+
const = constant_name(v.name)
|
|
54
|
+
mod.const_set(const, v.number) if const && !mod.const_defined?(const, false)
|
|
55
|
+
end
|
|
56
|
+
mod.instance_variable_set(:@descriptor, descriptor)
|
|
57
|
+
mod.instance_variable_set(:@__names, Ractor.make_shareable(names))
|
|
58
|
+
mod.instance_variable_set(:@__numbers, Ractor.make_shareable(numbers))
|
|
59
|
+
mod
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @return [String, nil] the value name as a Ruby constant name: first
|
|
63
|
+
# letter upper-cased, nil when that is still not a constant name
|
|
64
|
+
# @api private
|
|
65
|
+
def self.constant_name(name)
|
|
66
|
+
const = name.sub(/\A[a-z]/, &:upcase)
|
|
67
|
+
const if /\A[A-Z]\w*\z/.match?(const)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
# Raised for malformed wire input. {#offset} is the byte position in the
|
|
5
|
+
# decoded buffer where the problem was found.
|
|
6
|
+
class DecodeError < Error
|
|
7
|
+
# @return [Integer, nil]
|
|
8
|
+
attr_reader :offset
|
|
9
|
+
|
|
10
|
+
def initialize(message, offset: nil)
|
|
11
|
+
@offset = offset
|
|
12
|
+
super(offset ? "#{message} at byte #{offset}" : message)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Raised when encoding a message whose stored values cannot be written
|
|
17
|
+
class EncodeError < Error; end
|
|
18
|
+
|
|
19
|
+
# Raised when a value of the wrong type, out of range or with invalid
|
|
20
|
+
# contents is assigned to a field. A subclass of Ruby's TypeError so that
|
|
21
|
+
# callers used to google-protobuf's errors can rescue it the same way.
|
|
22
|
+
class TypeError < ::TypeError; end
|
|
23
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Generated by protostar from google/protobuf/any.proto. Do not edit.
|
|
4
|
+
|
|
5
|
+
require "protostar"
|
|
6
|
+
|
|
7
|
+
Protostar::DSL.file(
|
|
8
|
+
"google/protobuf/any.proto",
|
|
9
|
+
package: "google.protobuf",
|
|
10
|
+
syntax: :proto3,
|
|
11
|
+
go_package: "google.golang.org/protobuf/types/known/anypb",
|
|
12
|
+
java_package: "com.google.protobuf",
|
|
13
|
+
java_outer_classname: "AnyProto",
|
|
14
|
+
java_multiple_files: true,
|
|
15
|
+
objc_class_prefix: "GPB",
|
|
16
|
+
csharp_namespace: "Google.Protobuf.WellKnownTypes"
|
|
17
|
+
) do |f|
|
|
18
|
+
# `Any` contains an arbitrary serialized protocol buffer message along with a
|
|
19
|
+
# URL that describes the type of the serialized message.
|
|
20
|
+
#
|
|
21
|
+
# In its binary encoding, an `Any` is an ordinary message; but in other wire
|
|
22
|
+
# forms like JSON, it has a special encoding. The format of the type URL is
|
|
23
|
+
# described on the `type_url` field.
|
|
24
|
+
#
|
|
25
|
+
# Protobuf APIs provide utilities to interact with `Any` values:
|
|
26
|
+
#
|
|
27
|
+
# - A 'pack' operation accepts a message and constructs a generic `Any` wrapper
|
|
28
|
+
# around it.
|
|
29
|
+
# - An 'unpack' operation reads the content of an `Any` message, either into an
|
|
30
|
+
# existing message or a new one. Unpack operations must check the type of the
|
|
31
|
+
# value they unpack against the declared `type_url`.
|
|
32
|
+
# - An 'is' operation decides whether an `Any` contains a message of the given
|
|
33
|
+
# type, i.e. whether it can 'unpack' that type.
|
|
34
|
+
#
|
|
35
|
+
# The JSON format representation of an `Any` follows one of these cases:
|
|
36
|
+
#
|
|
37
|
+
# - For types without special-cased JSON encodings, the JSON format
|
|
38
|
+
# representation of the `Any` is the same as that of the message, with an
|
|
39
|
+
# additional `@type` field which contains the type URL.
|
|
40
|
+
# - For types with special-cased JSON encodings (typically called 'well-known'
|
|
41
|
+
# types, listed in https://protobuf.dev/programming-guides/json/#any), the
|
|
42
|
+
# JSON format representation has a key `@type` which contains the type URL
|
|
43
|
+
# and a key `value` which contains the JSON-serialized value.
|
|
44
|
+
#
|
|
45
|
+
# The text format representation of an `Any` is like a message with one field
|
|
46
|
+
# whose name is the type URL in brackets. For example, an `Any` containing a
|
|
47
|
+
# `foo.Bar` message may be written `[type.googleapis.com/foo.Bar] { a: 2 }`.
|
|
48
|
+
f.message "Any" do |m|
|
|
49
|
+
# Identifies the type of the serialized Protobuf message with a URI reference
|
|
50
|
+
# consisting of a prefix ending in a slash and the fully-qualified type name.
|
|
51
|
+
#
|
|
52
|
+
# Example: type.googleapis.com/google.protobuf.StringValue
|
|
53
|
+
#
|
|
54
|
+
# This string must contain at least one `/` character, and the content after
|
|
55
|
+
# the last `/` must be the fully-qualified name of the type in canonical
|
|
56
|
+
# form, without a leading dot. Do not write a scheme on these URI references
|
|
57
|
+
# so that clients do not attempt to contact them.
|
|
58
|
+
#
|
|
59
|
+
# The prefix is arbitrary and Protobuf implementations are expected to
|
|
60
|
+
# simply strip off everything up to and including the last `/` to identify
|
|
61
|
+
# the type. `type.googleapis.com/` is a common default prefix that some
|
|
62
|
+
# legacy implementations require. This prefix does not indicate the origin of
|
|
63
|
+
# the type, and URIs containing it are not expected to respond to any
|
|
64
|
+
# requests.
|
|
65
|
+
#
|
|
66
|
+
# All type URL strings must be legal URI references with the additional
|
|
67
|
+
# restriction (for the text format) that the content of the reference
|
|
68
|
+
# must consist only of alphanumeric characters, percent-encoded escapes, and
|
|
69
|
+
# characters in the following set (not including the outer backticks):
|
|
70
|
+
# `/-.~_!$&()*+,;=`. Despite our allowing percent encodings, implementations
|
|
71
|
+
# should not unescape them to prevent confusion with existing parsers. For
|
|
72
|
+
# example, `type.googleapis.com%2FFoo` should be rejected.
|
|
73
|
+
#
|
|
74
|
+
# In the original design of `Any`, the possibility of launching a type
|
|
75
|
+
# resolution service at these type URLs was considered but Protobuf never
|
|
76
|
+
# implemented one and considers contacting these URLs to be problematic and
|
|
77
|
+
# a potential security issue. Do not attempt to contact type URLs.
|
|
78
|
+
m.field :type_url, 1, :string
|
|
79
|
+
# Holds a Protobuf serialization of the type described by type_url.
|
|
80
|
+
m.field :value, 2, :bytes
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
module Protostar
|
|
85
|
+
module Google
|
|
86
|
+
module Protobuf
|
|
87
|
+
Any = Protostar::DSL.message("google.protobuf.Any")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|