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,202 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Generated by protostar from google/protobuf/type.proto. Do not edit.
|
|
4
|
+
|
|
5
|
+
require "protostar"
|
|
6
|
+
require "protostar/google/protobuf/any_pb"
|
|
7
|
+
require "protostar/google/protobuf/source_context_pb"
|
|
8
|
+
|
|
9
|
+
Protostar::DSL.file(
|
|
10
|
+
"google/protobuf/type.proto",
|
|
11
|
+
package: "google.protobuf",
|
|
12
|
+
syntax: :proto3,
|
|
13
|
+
dependencies: ["google/protobuf/any.proto", "google/protobuf/source_context.proto"],
|
|
14
|
+
cc_enable_arenas: true,
|
|
15
|
+
java_package: "com.google.protobuf",
|
|
16
|
+
java_outer_classname: "TypeProto",
|
|
17
|
+
java_multiple_files: true,
|
|
18
|
+
objc_class_prefix: "GPB",
|
|
19
|
+
csharp_namespace: "Google.Protobuf.WellKnownTypes",
|
|
20
|
+
go_package: "google.golang.org/protobuf/types/known/typepb"
|
|
21
|
+
) do |f|
|
|
22
|
+
# A protocol buffer message type.
|
|
23
|
+
#
|
|
24
|
+
# New usages of this message as an alternative to DescriptorProto are strongly
|
|
25
|
+
# discouraged. This message does not reliability preserve all information
|
|
26
|
+
# necessary to model the schema and preserve semantics. Instead make use of
|
|
27
|
+
# FileDescriptorSet which preserves the necessary information.
|
|
28
|
+
f.message "Type" do |m|
|
|
29
|
+
# The fully qualified message name.
|
|
30
|
+
m.field :name, 1, :string
|
|
31
|
+
# The list of fields.
|
|
32
|
+
m.field :fields, 2, :message, ".google.protobuf.Field", label: :repeated
|
|
33
|
+
# The list of types appearing in `oneof` definitions in this type.
|
|
34
|
+
m.field :oneofs, 3, :string, label: :repeated
|
|
35
|
+
# The protocol buffer options.
|
|
36
|
+
m.field :options, 4, :message, ".google.protobuf.Option", label: :repeated
|
|
37
|
+
# The source context.
|
|
38
|
+
m.field :source_context, 5, :message, ".google.protobuf.SourceContext"
|
|
39
|
+
# The source syntax.
|
|
40
|
+
m.field :syntax, 6, :enum, ".google.protobuf.Syntax"
|
|
41
|
+
# The source edition string, only valid when syntax is SYNTAX_EDITIONS.
|
|
42
|
+
m.field :edition, 7, :string
|
|
43
|
+
end
|
|
44
|
+
# A single field of a message type.
|
|
45
|
+
#
|
|
46
|
+
# New usages of this message as an alternative to FieldDescriptorProto are
|
|
47
|
+
# strongly discouraged. This message does not reliability preserve all
|
|
48
|
+
# information necessary to model the schema and preserve semantics. Instead
|
|
49
|
+
# make use of FileDescriptorSet which preserves the necessary information.
|
|
50
|
+
f.message "Field" do |m|
|
|
51
|
+
# The field type.
|
|
52
|
+
m.field :kind, 1, :enum, ".google.protobuf.Field.Kind"
|
|
53
|
+
# The field cardinality.
|
|
54
|
+
m.field :cardinality, 2, :enum, ".google.protobuf.Field.Cardinality"
|
|
55
|
+
# The field number.
|
|
56
|
+
m.field :number, 3, :int32
|
|
57
|
+
# The field name.
|
|
58
|
+
m.field :name, 4, :string
|
|
59
|
+
# The field type URL, without the scheme, for message or enumeration
|
|
60
|
+
# types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
|
|
61
|
+
m.field :type_url, 6, :string
|
|
62
|
+
# The index of the field type in `Type.oneofs`, for message or enumeration
|
|
63
|
+
# types. The first type has index 1; zero means the type is not in the list.
|
|
64
|
+
m.field :oneof_index, 7, :int32
|
|
65
|
+
# Whether to use alternative packed wire representation.
|
|
66
|
+
m.field :packed, 8, :bool
|
|
67
|
+
# The protocol buffer options.
|
|
68
|
+
m.field :options, 9, :message, ".google.protobuf.Option", label: :repeated
|
|
69
|
+
# The field JSON name.
|
|
70
|
+
m.field :json_name, 10, :string
|
|
71
|
+
# The string value of the default value of this field. Proto2 syntax only.
|
|
72
|
+
m.field :default_value, 11, :string
|
|
73
|
+
# Basic field types.
|
|
74
|
+
m.enum "Kind" do |e|
|
|
75
|
+
# Field type unknown.
|
|
76
|
+
e.value :TYPE_UNKNOWN, 0
|
|
77
|
+
# Field type double.
|
|
78
|
+
e.value :TYPE_DOUBLE, 1
|
|
79
|
+
# Field type float.
|
|
80
|
+
e.value :TYPE_FLOAT, 2
|
|
81
|
+
# Field type int64.
|
|
82
|
+
e.value :TYPE_INT64, 3
|
|
83
|
+
# Field type uint64.
|
|
84
|
+
e.value :TYPE_UINT64, 4
|
|
85
|
+
# Field type int32.
|
|
86
|
+
e.value :TYPE_INT32, 5
|
|
87
|
+
# Field type fixed64.
|
|
88
|
+
e.value :TYPE_FIXED64, 6
|
|
89
|
+
# Field type fixed32.
|
|
90
|
+
e.value :TYPE_FIXED32, 7
|
|
91
|
+
# Field type bool.
|
|
92
|
+
e.value :TYPE_BOOL, 8
|
|
93
|
+
# Field type string.
|
|
94
|
+
e.value :TYPE_STRING, 9
|
|
95
|
+
# Field type group. Proto2 syntax only, and deprecated.
|
|
96
|
+
e.value :TYPE_GROUP, 10
|
|
97
|
+
# Field type message.
|
|
98
|
+
e.value :TYPE_MESSAGE, 11
|
|
99
|
+
# Field type bytes.
|
|
100
|
+
e.value :TYPE_BYTES, 12
|
|
101
|
+
# Field type uint32.
|
|
102
|
+
e.value :TYPE_UINT32, 13
|
|
103
|
+
# Field type enum.
|
|
104
|
+
e.value :TYPE_ENUM, 14
|
|
105
|
+
# Field type sfixed32.
|
|
106
|
+
e.value :TYPE_SFIXED32, 15
|
|
107
|
+
# Field type sfixed64.
|
|
108
|
+
e.value :TYPE_SFIXED64, 16
|
|
109
|
+
# Field type sint32.
|
|
110
|
+
e.value :TYPE_SINT32, 17
|
|
111
|
+
# Field type sint64.
|
|
112
|
+
e.value :TYPE_SINT64, 18
|
|
113
|
+
end
|
|
114
|
+
# Whether a field is optional, required, or repeated.
|
|
115
|
+
m.enum "Cardinality" do |e|
|
|
116
|
+
# For fields with unknown cardinality.
|
|
117
|
+
e.value :CARDINALITY_UNKNOWN, 0
|
|
118
|
+
# For optional fields.
|
|
119
|
+
e.value :CARDINALITY_OPTIONAL, 1
|
|
120
|
+
# For required fields. Proto2 syntax only.
|
|
121
|
+
e.value :CARDINALITY_REQUIRED, 2
|
|
122
|
+
# For repeated fields.
|
|
123
|
+
e.value :CARDINALITY_REPEATED, 3
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
# Enum type definition.
|
|
127
|
+
#
|
|
128
|
+
# New usages of this message as an alternative to EnumDescriptorProto are
|
|
129
|
+
# strongly discouraged. This message does not reliability preserve all
|
|
130
|
+
# information necessary to model the schema and preserve semantics. Instead
|
|
131
|
+
# make use of FileDescriptorSet which preserves the necessary information.
|
|
132
|
+
f.message "Enum" do |m|
|
|
133
|
+
# Enum type name.
|
|
134
|
+
m.field :name, 1, :string
|
|
135
|
+
# Enum value definitions.
|
|
136
|
+
m.field :enumvalue, 2, :message, ".google.protobuf.EnumValue", label: :repeated
|
|
137
|
+
# Protocol buffer options.
|
|
138
|
+
m.field :options, 3, :message, ".google.protobuf.Option", label: :repeated
|
|
139
|
+
# The source context.
|
|
140
|
+
m.field :source_context, 4, :message, ".google.protobuf.SourceContext"
|
|
141
|
+
# The source syntax.
|
|
142
|
+
m.field :syntax, 5, :enum, ".google.protobuf.Syntax"
|
|
143
|
+
# The source edition string, only valid when syntax is SYNTAX_EDITIONS.
|
|
144
|
+
m.field :edition, 6, :string
|
|
145
|
+
end
|
|
146
|
+
# Enum value definition.
|
|
147
|
+
#
|
|
148
|
+
# New usages of this message as an alternative to EnumValueDescriptorProto are
|
|
149
|
+
# strongly discouraged. This message does not reliability preserve all
|
|
150
|
+
# information necessary to model the schema and preserve semantics. Instead
|
|
151
|
+
# make use of FileDescriptorSet which preserves the necessary information.
|
|
152
|
+
f.message "EnumValue" do |m|
|
|
153
|
+
# Enum value name.
|
|
154
|
+
m.field :name, 1, :string
|
|
155
|
+
# Enum value number.
|
|
156
|
+
m.field :number, 2, :int32
|
|
157
|
+
# Protocol buffer options.
|
|
158
|
+
m.field :options, 3, :message, ".google.protobuf.Option", label: :repeated
|
|
159
|
+
end
|
|
160
|
+
# A protocol buffer option, which can be attached to a message, field,
|
|
161
|
+
# enumeration, etc.
|
|
162
|
+
#
|
|
163
|
+
# New usages of this message as an alternative to FileOptions, MessageOptions,
|
|
164
|
+
# FieldOptions, EnumOptions, EnumValueOptions, ServiceOptions, or MethodOptions
|
|
165
|
+
# are strongly discouraged.
|
|
166
|
+
f.message "Option" do |m|
|
|
167
|
+
# The option's name. For protobuf built-in options (options defined in
|
|
168
|
+
# descriptor.proto), this is the short name. For example, `"map_entry"`.
|
|
169
|
+
# For custom options, it should be the fully-qualified name. For example,
|
|
170
|
+
# `"google.api.http"`.
|
|
171
|
+
m.field :name, 1, :string
|
|
172
|
+
# The option's value packed in an Any message. If the value is a primitive,
|
|
173
|
+
# the corresponding wrapper type defined in google/protobuf/wrappers.proto
|
|
174
|
+
# should be used. If the value is an enum, it should be stored as an int32
|
|
175
|
+
# value using the google.protobuf.Int32Value type.
|
|
176
|
+
m.field :value, 2, :message, ".google.protobuf.Any"
|
|
177
|
+
end
|
|
178
|
+
# The syntax in which a protocol buffer element is defined.
|
|
179
|
+
f.enum "Syntax" do |e|
|
|
180
|
+
# Syntax `proto2`.
|
|
181
|
+
e.value :SYNTAX_PROTO2, 0
|
|
182
|
+
# Syntax `proto3`.
|
|
183
|
+
e.value :SYNTAX_PROTO3, 1
|
|
184
|
+
# Syntax `editions`.
|
|
185
|
+
e.value :SYNTAX_EDITIONS, 2
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
module Protostar
|
|
190
|
+
module Google
|
|
191
|
+
module Protobuf
|
|
192
|
+
Type = Protostar::DSL.message("google.protobuf.Type")
|
|
193
|
+
Field = Protostar::DSL.message("google.protobuf.Field")
|
|
194
|
+
Field::Kind = Protostar::DSL.enum("google.protobuf.Field.Kind")
|
|
195
|
+
Field::Cardinality = Protostar::DSL.enum("google.protobuf.Field.Cardinality")
|
|
196
|
+
Enum = Protostar::DSL.message("google.protobuf.Enum")
|
|
197
|
+
EnumValue = Protostar::DSL.message("google.protobuf.EnumValue")
|
|
198
|
+
Option = Protostar::DSL.message("google.protobuf.Option")
|
|
199
|
+
Syntax = Protostar::DSL.enum("google.protobuf.Syntax")
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Generated by protostar from google/protobuf/wrappers.proto. Do not edit.
|
|
4
|
+
|
|
5
|
+
require "protostar"
|
|
6
|
+
|
|
7
|
+
Protostar::DSL.file(
|
|
8
|
+
"google/protobuf/wrappers.proto",
|
|
9
|
+
package: "google.protobuf",
|
|
10
|
+
syntax: :proto3,
|
|
11
|
+
cc_enable_arenas: true,
|
|
12
|
+
go_package: "google.golang.org/protobuf/types/known/wrapperspb",
|
|
13
|
+
java_package: "com.google.protobuf",
|
|
14
|
+
java_outer_classname: "WrappersProto",
|
|
15
|
+
java_multiple_files: true,
|
|
16
|
+
objc_class_prefix: "GPB",
|
|
17
|
+
csharp_namespace: "Google.Protobuf.WellKnownTypes"
|
|
18
|
+
) do |f|
|
|
19
|
+
# Wrapper message for `double`.
|
|
20
|
+
#
|
|
21
|
+
# The JSON representation for `DoubleValue` is JSON number.
|
|
22
|
+
#
|
|
23
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
24
|
+
# has no plan to be removed.
|
|
25
|
+
f.message "DoubleValue" do |m|
|
|
26
|
+
# The double value.
|
|
27
|
+
m.field :value, 1, :double
|
|
28
|
+
end
|
|
29
|
+
# Wrapper message for `float`.
|
|
30
|
+
#
|
|
31
|
+
# The JSON representation for `FloatValue` is JSON number.
|
|
32
|
+
#
|
|
33
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
34
|
+
# has no plan to be removed.
|
|
35
|
+
f.message "FloatValue" do |m|
|
|
36
|
+
# The float value.
|
|
37
|
+
m.field :value, 1, :float
|
|
38
|
+
end
|
|
39
|
+
# Wrapper message for `int64`.
|
|
40
|
+
#
|
|
41
|
+
# The JSON representation for `Int64Value` is JSON string.
|
|
42
|
+
#
|
|
43
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
44
|
+
# has no plan to be removed.
|
|
45
|
+
f.message "Int64Value" do |m|
|
|
46
|
+
# The int64 value.
|
|
47
|
+
m.field :value, 1, :int64
|
|
48
|
+
end
|
|
49
|
+
# Wrapper message for `uint64`.
|
|
50
|
+
#
|
|
51
|
+
# The JSON representation for `UInt64Value` is JSON string.
|
|
52
|
+
#
|
|
53
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
54
|
+
# has no plan to be removed.
|
|
55
|
+
f.message "UInt64Value" do |m|
|
|
56
|
+
# The uint64 value.
|
|
57
|
+
m.field :value, 1, :uint64
|
|
58
|
+
end
|
|
59
|
+
# Wrapper message for `int32`.
|
|
60
|
+
#
|
|
61
|
+
# The JSON representation for `Int32Value` is JSON number.
|
|
62
|
+
#
|
|
63
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
64
|
+
# has no plan to be removed.
|
|
65
|
+
f.message "Int32Value" do |m|
|
|
66
|
+
# The int32 value.
|
|
67
|
+
m.field :value, 1, :int32
|
|
68
|
+
end
|
|
69
|
+
# Wrapper message for `uint32`.
|
|
70
|
+
#
|
|
71
|
+
# The JSON representation for `UInt32Value` is JSON number.
|
|
72
|
+
#
|
|
73
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
74
|
+
# has no plan to be removed.
|
|
75
|
+
f.message "UInt32Value" do |m|
|
|
76
|
+
# The uint32 value.
|
|
77
|
+
m.field :value, 1, :uint32
|
|
78
|
+
end
|
|
79
|
+
# Wrapper message for `bool`.
|
|
80
|
+
#
|
|
81
|
+
# The JSON representation for `BoolValue` is JSON `true` and `false`.
|
|
82
|
+
#
|
|
83
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
84
|
+
# has no plan to be removed.
|
|
85
|
+
f.message "BoolValue" do |m|
|
|
86
|
+
# The bool value.
|
|
87
|
+
m.field :value, 1, :bool
|
|
88
|
+
end
|
|
89
|
+
# Wrapper message for `string`.
|
|
90
|
+
#
|
|
91
|
+
# The JSON representation for `StringValue` is JSON string.
|
|
92
|
+
#
|
|
93
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
94
|
+
# has no plan to be removed.
|
|
95
|
+
f.message "StringValue" do |m|
|
|
96
|
+
# The string value.
|
|
97
|
+
m.field :value, 1, :string
|
|
98
|
+
end
|
|
99
|
+
# Wrapper message for `bytes`.
|
|
100
|
+
#
|
|
101
|
+
# The JSON representation for `BytesValue` is JSON string.
|
|
102
|
+
#
|
|
103
|
+
# Not recommended for use in new APIs, but still useful for legacy APIs and
|
|
104
|
+
# has no plan to be removed.
|
|
105
|
+
f.message "BytesValue" do |m|
|
|
106
|
+
# The bytes value.
|
|
107
|
+
m.field :value, 1, :bytes
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
module Protostar
|
|
112
|
+
module Google
|
|
113
|
+
module Protobuf
|
|
114
|
+
DoubleValue = Protostar::DSL.message("google.protobuf.DoubleValue")
|
|
115
|
+
FloatValue = Protostar::DSL.message("google.protobuf.FloatValue")
|
|
116
|
+
Int64Value = Protostar::DSL.message("google.protobuf.Int64Value")
|
|
117
|
+
UInt64Value = Protostar::DSL.message("google.protobuf.UInt64Value")
|
|
118
|
+
Int32Value = Protostar::DSL.message("google.protobuf.Int32Value")
|
|
119
|
+
UInt32Value = Protostar::DSL.message("google.protobuf.UInt32Value")
|
|
120
|
+
BoolValue = Protostar::DSL.message("google.protobuf.BoolValue")
|
|
121
|
+
StringValue = Protostar::DSL.message("google.protobuf.StringValue")
|
|
122
|
+
BytesValue = Protostar::DSL.message("google.protobuf.BytesValue")
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Makes `require "google/protobuf"` load the google-protobuf shim bundled with protostar
|
|
4
|
+
# instead of Google's gem, for grpc and anything else that requires it. Require this
|
|
5
|
+
# before anything else touches google/protobuf:
|
|
6
|
+
#
|
|
7
|
+
# require "protostar/google_protobuf_shim"
|
|
8
|
+
# require "grpc"
|
|
9
|
+
#
|
|
10
|
+
# The shim's files are in the gem but not on its load path, so a plain
|
|
11
|
+
# `require "protostar"` leaves Google's gem alone.
|
|
12
|
+
shim_loaded = defined?(::Google::Protobuf::IMPLEMENTATION) && ::Google::Protobuf::IMPLEMENTATION == :PROTOSTAR
|
|
13
|
+
if defined?(::Google::Protobuf::DescriptorPool) && !shim_loaded
|
|
14
|
+
raise LoadError, "Google's google-protobuf is already loaded, so the protostar shim cannot replace it. " \
|
|
15
|
+
"Require protostar/google_protobuf_shim before anything requires google/protobuf"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The shim may be loaded already, from the same files or from the git-sourced gem
|
|
19
|
+
unless shim_loaded
|
|
20
|
+
shim_lib = File.expand_path("../../shims/google-protobuf/lib", __dir__)
|
|
21
|
+
# In front of Google's gem, should Bundler have activated it for grpc
|
|
22
|
+
$LOAD_PATH.unshift(shim_lib) unless $LOAD_PATH.include?(shim_lib)
|
|
23
|
+
require "google/protobuf"
|
|
24
|
+
end
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Protostar
|
|
4
|
+
module JSON
|
|
5
|
+
# Writes a message as proto3 JSON the way google-protobuf's Ruby gem
|
|
6
|
+
# does: compact, fields in declaration order, unknown fields left out.
|
|
7
|
+
# @api private
|
|
8
|
+
class Encoder
|
|
9
|
+
F = Message::FieldInfo
|
|
10
|
+
|
|
11
|
+
# Messages whose JSON is not an object of their fields
|
|
12
|
+
SPECIAL = {
|
|
13
|
+
"google.protobuf.Any" => :any,
|
|
14
|
+
"google.protobuf.Timestamp" => :timestamp,
|
|
15
|
+
"google.protobuf.Duration" => :duration,
|
|
16
|
+
"google.protobuf.FieldMask" => :field_mask,
|
|
17
|
+
"google.protobuf.Struct" => :struct,
|
|
18
|
+
"google.protobuf.Value" => :value,
|
|
19
|
+
"google.protobuf.ListValue" => :list_value,
|
|
20
|
+
"google.protobuf.DoubleValue" => :wrapper,
|
|
21
|
+
"google.protobuf.FloatValue" => :wrapper,
|
|
22
|
+
"google.protobuf.Int64Value" => :wrapper,
|
|
23
|
+
"google.protobuf.UInt64Value" => :wrapper,
|
|
24
|
+
"google.protobuf.Int32Value" => :wrapper,
|
|
25
|
+
"google.protobuf.UInt32Value" => :wrapper,
|
|
26
|
+
"google.protobuf.BoolValue" => :wrapper,
|
|
27
|
+
"google.protobuf.StringValue" => :wrapper,
|
|
28
|
+
"google.protobuf.BytesValue" => :wrapper
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
NULL_VALUE = "google.protobuf.NullValue"
|
|
32
|
+
|
|
33
|
+
ESCAPES = Ractor.make_shareable((0..0x1f).to_h { |b| [b.chr, format("\\u%04x", b)] }.merge(
|
|
34
|
+
"\n" => "\\n", "\r" => "\\r", "\t" => "\\t", "\f" => "\\f", "\b" => "\\b", "\"" => "\\\"", "\\" => "\\\\"
|
|
35
|
+
))
|
|
36
|
+
ESCAPED = /["\\\x00-\x1f]/
|
|
37
|
+
|
|
38
|
+
# Seconds of 0001-01-01T00:00:00Z and 9999-12-31T23:59:59Z
|
|
39
|
+
TIMESTAMP_MIN = -62_135_596_800
|
|
40
|
+
TIMESTAMP_MAX = 253_402_300_799
|
|
41
|
+
DURATION_MAX = 315_576_000_000
|
|
42
|
+
|
|
43
|
+
# @param preserve_proto_field_names [Boolean] field names as in the .proto, not lowerCamel
|
|
44
|
+
# @param emit_defaults [Boolean] also fields without presence at their default, and empty
|
|
45
|
+
# repeated fields and maps; never unset message fields or oneof members
|
|
46
|
+
# @param format_enums_as_integers [Boolean]
|
|
47
|
+
# @param registry [Types::Registry] where the types inside Any are looked up
|
|
48
|
+
def initialize(preserve_proto_field_names: false, emit_defaults: false, format_enums_as_integers: false,
|
|
49
|
+
registry: nil, preserve_proto_fieldnames: nil)
|
|
50
|
+
@proto_names = preserve_proto_fieldnames.nil? ? preserve_proto_field_names : preserve_proto_fieldnames
|
|
51
|
+
@emit_defaults = emit_defaults
|
|
52
|
+
@enums_as_integers = format_enums_as_integers
|
|
53
|
+
@registry = registry
|
|
54
|
+
@path = []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param message [Message]
|
|
58
|
+
# @return [String] UTF-8
|
|
59
|
+
def encode(message)
|
|
60
|
+
out = +""
|
|
61
|
+
message(message, out)
|
|
62
|
+
out.force_encoding(Encoding::UTF_8)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def message(msg, out)
|
|
68
|
+
special = SPECIAL[msg.class.descriptor.full_name]
|
|
69
|
+
if special
|
|
70
|
+
send(special, msg, out)
|
|
71
|
+
else
|
|
72
|
+
out << "{"
|
|
73
|
+
fields(msg, out, true)
|
|
74
|
+
out << "}"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Writes the fields of a message, each preceded by a comma unless it is
|
|
79
|
+
# the first; returns whether nothing was written
|
|
80
|
+
def fields(msg, out, first)
|
|
81
|
+
values = msg.__values
|
|
82
|
+
msg.class.__fields.each do |info|
|
|
83
|
+
v = values[info.index]
|
|
84
|
+
if @emit_defaults
|
|
85
|
+
next if v.nil? && info.presence
|
|
86
|
+
elsif v.nil?
|
|
87
|
+
next
|
|
88
|
+
elsif info.map || info.repeated
|
|
89
|
+
next if v.empty?
|
|
90
|
+
elsif !info.presence && info.zero?(v)
|
|
91
|
+
next
|
|
92
|
+
end
|
|
93
|
+
out << "," unless first
|
|
94
|
+
first = false
|
|
95
|
+
string(@proto_names ? info.name : info.descriptor.json_name, out)
|
|
96
|
+
out << ":"
|
|
97
|
+
@path << info.name
|
|
98
|
+
if info.map
|
|
99
|
+
map(info, v || Message::EMPTY_HASH, out)
|
|
100
|
+
elsif info.repeated
|
|
101
|
+
out << "["
|
|
102
|
+
(v || Message::EMPTY_ARRAY).each_with_index do |e, i|
|
|
103
|
+
out << "," unless i == 0
|
|
104
|
+
@path << i
|
|
105
|
+
single(info, e, out)
|
|
106
|
+
@path.pop
|
|
107
|
+
end
|
|
108
|
+
out << "]"
|
|
109
|
+
else
|
|
110
|
+
single(info, v, out)
|
|
111
|
+
end
|
|
112
|
+
@path.pop
|
|
113
|
+
end
|
|
114
|
+
msg.unknown_fields.empty? ? first : extensions(msg, out, first)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Extensions travel as unknown fields; those known to the message's file
|
|
118
|
+
# and its imports are written as "[full.name]", the rest left out
|
|
119
|
+
def extensions(msg, out, first)
|
|
120
|
+
@extensions ||= Text::Extensions.new(@registry, nil)
|
|
121
|
+
known = @extensions.of(msg.class.descriptor)
|
|
122
|
+
return first if known.empty?
|
|
123
|
+
msg.unknown_fields.group_by(&:number).sort_by(&:first).each do |number, list|
|
|
124
|
+
field = known[number] or next
|
|
125
|
+
info = @extensions.info(field) or next
|
|
126
|
+
values = @extensions.read(info, list)
|
|
127
|
+
next if values.nil? || values.empty?
|
|
128
|
+
out << "," unless first
|
|
129
|
+
first = false
|
|
130
|
+
name = "[#{field.full_name}]"
|
|
131
|
+
string(name, out)
|
|
132
|
+
out << ":"
|
|
133
|
+
@path << name
|
|
134
|
+
if info.repeated
|
|
135
|
+
out << "["
|
|
136
|
+
values.each_with_index do |e, i|
|
|
137
|
+
out << "," unless i == 0
|
|
138
|
+
single(info, e, out)
|
|
139
|
+
end
|
|
140
|
+
out << "]"
|
|
141
|
+
else
|
|
142
|
+
single(info, values.last, out)
|
|
143
|
+
end
|
|
144
|
+
@path.pop
|
|
145
|
+
end
|
|
146
|
+
first
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def map(info, hash, out)
|
|
150
|
+
key = info.key
|
|
151
|
+
value = info.value
|
|
152
|
+
out << "{"
|
|
153
|
+
first = true
|
|
154
|
+
hash.each do |k, v|
|
|
155
|
+
out << "," unless first
|
|
156
|
+
first = false
|
|
157
|
+
if key.kind == F::STRING
|
|
158
|
+
string(k, out)
|
|
159
|
+
else
|
|
160
|
+
out << "\"" << k.to_s << "\""
|
|
161
|
+
end
|
|
162
|
+
out << ":"
|
|
163
|
+
@path << Path::MapKey.new(k)
|
|
164
|
+
single(value, v, out)
|
|
165
|
+
@path.pop
|
|
166
|
+
end
|
|
167
|
+
out << "}"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def single(info, v, out)
|
|
171
|
+
case info.kind
|
|
172
|
+
when F::INT32, F::SINT32, F::SFIXED32, F::UINT32, F::FIXED32 then out << v.to_s
|
|
173
|
+
when F::INT64, F::SINT64, F::SFIXED64, F::UINT64, F::FIXED64 then out << "\"" << v.to_s << "\""
|
|
174
|
+
when F::DOUBLE then double(v, out)
|
|
175
|
+
when F::FLOAT then float(v, out)
|
|
176
|
+
when F::BOOL then out << (v ? "true" : "false")
|
|
177
|
+
when F::STRING then string(v, out)
|
|
178
|
+
when F::BYTES then out << "\"" << [v].pack("m0") << "\""
|
|
179
|
+
when F::ENUM then enum(info, v, out)
|
|
180
|
+
else message(v, out)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def enum(info, v, out)
|
|
185
|
+
if info.enum_module.descriptor.full_name == NULL_VALUE
|
|
186
|
+
out << "null"
|
|
187
|
+
elsif v.is_a?(Symbol) && !@enums_as_integers
|
|
188
|
+
out << "\"" << v.name << "\""
|
|
189
|
+
else
|
|
190
|
+
out << (v.is_a?(Symbol) ? info.enum_numbers.fetch(v) : v).to_s
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def string(s, out)
|
|
195
|
+
# strings without UTF-8 validation (proto2) can hold anything
|
|
196
|
+
s = s.scrub unless s.valid_encoding?
|
|
197
|
+
out << "\"" << (ESCAPED.match?(s) ? s.gsub(ESCAPED, ESCAPES) : s) << "\""
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# upb's round-trip form: 15 significant digits, or 17 when 15 do not read back
|
|
201
|
+
def double(v, out)
|
|
202
|
+
return out << nonfinite(v) unless v.finite?
|
|
203
|
+
s = format("%.15g", v)
|
|
204
|
+
back = Float(s)
|
|
205
|
+
s = format("%.17g", v) unless back == v
|
|
206
|
+
out << s
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Same for single precision: 6 digits, or 9
|
|
210
|
+
def float(v, out)
|
|
211
|
+
return out << nonfinite(v) unless v.finite?
|
|
212
|
+
s = format("%.6g", v)
|
|
213
|
+
s = format("%.9g", v) unless Message::Coercion.float32(Float(s)) == v
|
|
214
|
+
out << s
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def nonfinite(v)
|
|
218
|
+
if v.nan? then "\"NaN\""
|
|
219
|
+
elsif v > 0 then "\"Infinity\""
|
|
220
|
+
else "\"-Infinity\""
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def fail!(message)
|
|
225
|
+
raise EncodeError.new(message, Path.to_s(@path))
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def get(msg, name)
|
|
229
|
+
msg.__values[msg.class.__by_name.fetch(name).index]
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def any(msg, out)
|
|
233
|
+
url = get(msg, "type_url") || ""
|
|
234
|
+
value = get(msg, "value") || ""
|
|
235
|
+
return out << "{}" if url.empty? && value.empty?
|
|
236
|
+
klass = any_class(url)
|
|
237
|
+
inner = begin
|
|
238
|
+
klass.decode(value)
|
|
239
|
+
rescue DecodeError => e
|
|
240
|
+
fail!("cannot decode the #{klass.descriptor.full_name} inside Any: #{e.message}")
|
|
241
|
+
end
|
|
242
|
+
out << "{\"@type\":"
|
|
243
|
+
string(url, out)
|
|
244
|
+
if SPECIAL.key?(klass.descriptor.full_name)
|
|
245
|
+
out << ",\"value\":"
|
|
246
|
+
message(inner, out)
|
|
247
|
+
else
|
|
248
|
+
fields(inner, out, false)
|
|
249
|
+
end
|
|
250
|
+
out << "}"
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def any_class(url)
|
|
254
|
+
slash = url.rindex("/")
|
|
255
|
+
fail!("bad type URL #{url.inspect} in Any") if slash.nil? || slash == 0
|
|
256
|
+
name = url[(slash + 1)..]
|
|
257
|
+
klass = Types.find(name, registry: @registry || Types.registry)
|
|
258
|
+
fail!("cannot find the type #{name.inspect} of an Any") unless klass.is_a?(Class)
|
|
259
|
+
klass
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def timestamp(msg, out)
|
|
263
|
+
seconds = get(msg, "seconds") || 0
|
|
264
|
+
nanos = get(msg, "nanos") || 0
|
|
265
|
+
fail!("Timestamp before 0001-01-01T00:00:00Z") if seconds < TIMESTAMP_MIN
|
|
266
|
+
fail!("Timestamp after 9999-12-31T23:59:59Z") if seconds > TIMESTAMP_MAX
|
|
267
|
+
fail!("Timestamp nanos out of range: #{nanos}") unless (0..999_999_999).cover?(nanos)
|
|
268
|
+
time = ::Time.at(seconds).utc
|
|
269
|
+
out << "\"" << time.strftime("%Y-%m-%dT%H:%M:%S") << fraction(nanos) << "Z\""
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def duration(msg, out)
|
|
273
|
+
seconds = get(msg, "seconds") || 0
|
|
274
|
+
nanos = get(msg, "nanos") || 0
|
|
275
|
+
fail!("Duration out of range: #{seconds}s") if seconds.abs > DURATION_MAX
|
|
276
|
+
fail!("Duration nanos out of range: #{nanos}") if nanos.abs > 999_999_999
|
|
277
|
+
fail!("Duration seconds and nanos have different signs") if (seconds < 0 && nanos > 0) || (seconds > 0 && nanos < 0)
|
|
278
|
+
out << "\""
|
|
279
|
+
out << "-" if seconds < 0 || nanos < 0
|
|
280
|
+
out << seconds.abs.to_s << fraction(nanos.abs) << "s\""
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# 0, 3, 6 or 9 digits, as few as the value needs
|
|
284
|
+
def fraction(nanos)
|
|
285
|
+
if nanos == 0 then ""
|
|
286
|
+
elsif nanos % 1_000_000 == 0 then format(".%03d", nanos / 1_000_000)
|
|
287
|
+
elsif nanos % 1000 == 0 then format(".%06d", nanos / 1000)
|
|
288
|
+
else format(".%09d", nanos)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def field_mask(msg, out)
|
|
293
|
+
paths = get(msg, "paths") || Message::EMPTY_ARRAY
|
|
294
|
+
camel = paths.map do |path|
|
|
295
|
+
fail!("FieldMask path #{path.inspect} has an upper-case letter and cannot round-trip through JSON") if /[A-Z]/.match?(path)
|
|
296
|
+
if /_(?![a-z])/.match?(path)
|
|
297
|
+
fail!("FieldMask path #{path.inspect} has an underscore not followed by a lower-case letter and cannot round-trip through JSON")
|
|
298
|
+
end
|
|
299
|
+
path.gsub(/_([a-z])/) { $1.upcase }
|
|
300
|
+
end
|
|
301
|
+
string(camel.join(","), out)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def struct(msg, out)
|
|
305
|
+
info = msg.class.__by_name.fetch("fields")
|
|
306
|
+
map(info, get(msg, "fields") || Message::EMPTY_HASH, out)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def list_value(msg, out)
|
|
310
|
+
out << "["
|
|
311
|
+
(get(msg, "values") || Message::EMPTY_ARRAY).each_with_index do |v, i|
|
|
312
|
+
out << "," unless i == 0
|
|
313
|
+
@path << i
|
|
314
|
+
message(v, out)
|
|
315
|
+
@path.pop
|
|
316
|
+
end
|
|
317
|
+
out << "]"
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def value(msg, out)
|
|
321
|
+
kind = msg.which_kind
|
|
322
|
+
fail!("Value has no kind set") unless kind
|
|
323
|
+
info = msg.class.__by_name.fetch(kind)
|
|
324
|
+
v = msg.__values[info.index]
|
|
325
|
+
case info.name
|
|
326
|
+
when "null_value" then out << "null"
|
|
327
|
+
when "number_value"
|
|
328
|
+
fail!("Value cannot hold #{v}, which would read back as a string") unless v.finite?
|
|
329
|
+
double(v, out)
|
|
330
|
+
else single(info, v, out)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def wrapper(msg, out)
|
|
335
|
+
info = msg.class.__by_name.fetch("value")
|
|
336
|
+
single(info, msg.__values[info.index] || info.default, out)
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|