From bd52d0483987f1a5186fc3daa261d1d76a787bcf Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Thu, 13 Apr 2023 16:08:14 -0700 Subject: [PATCH] Change the Ruby code generator to emit a serialized proto instead of the DSL (#12319) This PR removes the DSL from the code generator, in anticipation of splitting the DSL out into a separate package. Given a .proto file like: ```proto syntax = "proto3"; package pkg; message TestMessage { optional int32 i32 = 1; optional TestMessage msg = 2; } ``` Generated code before: ```ruby # Generated by the protocol buffer compiler. DO NOT EDIT! # source: protoc_explorer/main.proto require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do add_file("test.proto", :syntax => :proto3) do add_message "pkg.TestMessage" do proto3_optional :i32, :int32, 1 proto3_optional :msg, :message, 2, "pkg.TestMessage" end end end module Pkg TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass end ``` Generated code after: ```ruby # frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: test.proto require 'google/protobuf' descriptor_data = "\n\ntest.proto\x12\x03pkg\"S\n\x0bTestMessage\x12\x10\n\x03i32\x18\x01 \x01(\x05H\x00\x88\x01\x01\x12\"\n\x03msg\x18\x02 \x01(\x0b\x32\x10.pkg.TestMessageH\x01\x88\x01\x01\x42\x06\n\x04_i32B\x06\n\x04_msgb\x06proto3" begin Google::Protobuf::DescriptorPool.generated_pool.add_serialized_file(descriptor_data) rescue TypeError => e # end module Pkg TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("pkg.TestMessage").msgclass end ``` This change fixes nearly all remaining conformance problems that existed previously. This is a side effect of moving from the DSL (which is lossy) to a serialized descriptor (which preserves all information). ## Backward Compatibility This change should be 100% compatible with Ruby Protobuf >= 3.18.0, released in Sept 2021. Additionally, it should be compatible with all existing users and deployments. However there is some special compatibility code I inserted to achieve this level of backward compatibility. Without the compatibility code, there is an edge case that could break backward compatibility. The existing code is lax in a way that the new code would be more strict. When we use a full serialized descriptor, it will contain a list of all `.proto` files imported by this file (whereas the DSL never added dependencies properly): https://github.com/protocolbuffers/protobuf/blob/dfb71558a2226718dc3bcf5df27cbc11c1f72382/src/google/protobuf/descriptor.proto#L65-L66 `add_serialized_file` will verify that all dependencies listed in the descriptor were previously added with `add_serialized_file`. Generally that should be fine, because the generated code will contain Ruby `require` statements for all dependencies, and the descriptor will fail to load anyway if the types we depend on were not previously defined in the DescriptorPool. But there is a potential for problems if there are ambiguities around file paths. For example, consider the following scenario: ```proto // foo/bar.proto syntax = "proto2"; message Bar {} ``` ```proto // foo/baz.proto syntax = "proto2"; import "bar.proto"; message Baz { optional Bar bar = 1; } ``` If you invoke `protoc` like so, it will work correctly: ``` $ protoc --ruby_out=. -Ifoo foo/bar.proto foo/baz.proto $ RUBYLIB=. ruby baz_pb.rb ``` However if you invoke `protoc` like so, and didn't have any compatibility code, it would fail to load: ``` $ protoc --ruby_out=. -I. -Ifoo foo/baz.proto $ protoc --ruby_out=. -I. -Ifoo foo/bar.proto $ RUBYLIB=foo ruby foo/baz_pb.rb foo/baz_pb.rb:10:in `add_serialized_file': Unable to build file to DescriptorPool: Depends on file 'bar.proto', but it has not been loaded (Google::Protobuf::TypeError) from foo/baz_pb.rb:10:in `
' ``` The problem is that `bar.proto` is being referred to by two different canonical names: `bar.proto` and `foo/bar.proto`. This is a user error: each import should always be referred to by a consistent full path. Hopefully user errors of this sort are rare, but it is hard to know without trying. The code in this PR prints a warning using `warn` if we detect that this edge case has occurred. We will plan to remove this compatibility code in the next major version. Closes #12319 COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/12319 from haberman:ruby-gencode-binary 5c0e8f20b10ef8cee4c885138a31e6054bfaf6e6 PiperOrigin-RevId: 524129023 --- conformance/failure_list_jruby.txt | 57 --- conformance/failure_list_ruby.txt | 58 --- .../java/com/google/protobuf/jruby/Utils.java | 5 +- .../compiler/ruby/ruby_generated_code_pb.rb | 84 ++--- .../ruby/ruby_generated_code_proto2_pb.rb | 85 ++--- .../ruby_generated_pkg_explicit_legacy_pb.rb | 28 +- .../ruby/ruby_generated_pkg_explicit_pb.rb | 28 +- .../ruby/ruby_generated_pkg_implicit_pb.rb | 28 +- .../protobuf/compiler/ruby/ruby_generator.cc | 357 ++++-------------- 9 files changed, 203 insertions(+), 527 deletions(-) diff --git a/conformance/failure_list_jruby.txt b/conformance/failure_list_jruby.txt index 516192ec00..c0d29804fe 100644 --- a/conformance/failure_list_jruby.txt +++ b/conformance/failure_list_jruby.txt @@ -2,34 +2,6 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse @@ -57,35 +29,6 @@ Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted -Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput Required.Proto3.JsonInput.EnumFieldNotQuoted Required.Proto3.JsonInput.Int32FieldLeadingZero Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index 3c744391cf..2fb4dc881f 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -1,60 +1,2 @@ -Recommended.Proto2.JsonInput.FieldNameExtension.Validator -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput diff --git a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java index 65de683b02..16136cb9b7 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java @@ -44,6 +44,7 @@ import org.jruby.runtime.Block; import org.jruby.runtime.Helpers; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ByteList; public class Utils { public static FieldDescriptor.Type rubyToFieldType(IRubyObject typeClass) { @@ -263,7 +264,9 @@ public class Utils { IRubyObject wrapped = encodeBytes ? RubyString.newString( - runtime, ((ByteString) value).toStringUtf8(), ASCIIEncoding.INSTANCE) + runtime, + new ByteList(((ByteString) value).toByteArray()), + ASCIIEncoding.INSTANCE) : RubyString.newString(runtime, ((ByteString) value).toByteArray()); wrapped.setFrozen(true); return wrapped; diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb index 256ac7c153..db3f4fb82c 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_code.proto @@ -5,67 +6,32 @@ require 'google/protobuf' require 'ruby_generated_code_proto2_import_pb' -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("ruby_generated_code.proto", :syntax => :proto3) do - add_message "A.B.C.TestMessage" do - optional :optional_int32, :int32, 1 - optional :optional_int64, :int64, 2 - optional :optional_uint32, :uint32, 3 - optional :optional_uint64, :uint64, 4 - optional :optional_bool, :bool, 5 - optional :optional_double, :double, 6 - optional :optional_float, :float, 7 - optional :optional_string, :string, 8 - optional :optional_bytes, :bytes, 9 - optional :optional_enum, :enum, 10, "A.B.C.TestEnum" - optional :optional_msg, :message, 11, "A.B.C.TestMessage" - optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage" - repeated :repeated_int32, :int32, 21 - repeated :repeated_int64, :int64, 22 - repeated :repeated_uint32, :uint32, 23 - repeated :repeated_uint64, :uint64, 24 - repeated :repeated_bool, :bool, 25 - repeated :repeated_double, :double, 26 - repeated :repeated_float, :float, 27 - repeated :repeated_string, :string, 28 - repeated :repeated_bytes, :bytes, 29 - repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum" - repeated :repeated_msg, :message, 31, "A.B.C.TestMessage" - map :map_int32_string, :int32, :string, 61 - map :map_int64_string, :int64, :string, 62 - map :map_uint32_string, :uint32, :string, 63 - map :map_uint64_string, :uint64, :string, 64 - map :map_bool_string, :bool, :string, 65 - map :map_string_string, :string, :string, 66 - map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage" - map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum" - map :map_string_int32, :string, :int32, 69 - map :map_string_bool, :string, :bool, 70 - optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage" - oneof :my_oneof do - optional :oneof_int32, :int32, 41 - optional :oneof_int64, :int64, 42 - optional :oneof_uint32, :uint32, 43 - optional :oneof_uint64, :uint64, 44 - optional :oneof_bool, :bool, 45 - optional :oneof_double, :double, 46 - optional :oneof_float, :float, 47 - optional :oneof_string, :string, 48 - optional :oneof_bytes, :bytes, 49 - optional :oneof_enum, :enum, 50, "A.B.C.TestEnum" - optional :oneof_msg, :message, 51, "A.B.C.TestMessage" - end - end - add_message "A.B.C.TestMessage.NestedMessage" do - optional :foo, :int32, 1 - end - add_enum "A.B.C.TestEnum" do - value :Default, 0 - value :A, 1 - value :B, 2 - value :C, 3 + +descriptor_data = "\n\x19ruby_generated_code.proto\x12\x05\x41.B.C\x1a\'ruby_generated_code_proto2_import.proto\"\x86\x12\n\x0bTestMessage\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05\x12\x16\n\x0eoptional_int64\x18\x02 \x01(\x03\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x17\n\x0foptional_uint64\x18\x04 \x01(\x04\x12\x15\n\roptional_bool\x18\x05 \x01(\x08\x12\x17\n\x0foptional_double\x18\x06 \x01(\x01\x12\x16\n\x0eoptional_float\x18\x07 \x01(\x02\x12\x17\n\x0foptional_string\x18\x08 \x01(\t\x12\x16\n\x0eoptional_bytes\x18\t \x01(\x0c\x12&\n\roptional_enum\x18\n \x01(\x0e\x32\x0f.A.B.C.TestEnum\x12(\n\x0coptional_msg\x18\x0b \x01(\x0b\x32\x12.A.B.C.TestMessage\x12>\n\x1aoptional_proto2_submessage\x18\x0c \x01(\x0b\x32\x1a.A.B.C.TestImportedMessage\x12\x16\n\x0erepeated_int32\x18\x15 \x03(\x05\x12\x16\n\x0erepeated_int64\x18\x16 \x03(\x03\x12\x17\n\x0frepeated_uint32\x18\x17 \x03(\r\x12\x17\n\x0frepeated_uint64\x18\x18 \x03(\x04\x12\x15\n\rrepeated_bool\x18\x19 \x03(\x08\x12\x17\n\x0frepeated_double\x18\x1a \x03(\x01\x12\x16\n\x0erepeated_float\x18\x1b \x03(\x02\x12\x17\n\x0frepeated_string\x18\x1c \x03(\t\x12\x16\n\x0erepeated_bytes\x18\x1d \x03(\x0c\x12&\n\rrepeated_enum\x18\x1e \x03(\x0e\x32\x0f.A.B.C.TestEnum\x12(\n\x0crepeated_msg\x18\x1f \x03(\x0b\x32\x12.A.B.C.TestMessage\x12\x15\n\x0boneof_int32\x18) \x01(\x05H\x00\x12\x15\n\x0boneof_int64\x18* \x01(\x03H\x00\x12\x16\n\x0coneof_uint32\x18+ \x01(\rH\x00\x12\x16\n\x0coneof_uint64\x18, \x01(\x04H\x00\x12\x14\n\noneof_bool\x18- \x01(\x08H\x00\x12\x16\n\x0coneof_double\x18. \x01(\x01H\x00\x12\x15\n\x0boneof_float\x18/ \x01(\x02H\x00\x12\x16\n\x0coneof_string\x18\x30 \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18\x31 \x01(\x0cH\x00\x12%\n\noneof_enum\x18\x32 \x01(\x0e\x32\x0f.A.B.C.TestEnumH\x00\x12\'\n\toneof_msg\x18\x33 \x01(\x0b\x32\x12.A.B.C.TestMessageH\x00\x12@\n\x10map_int32_string\x18= \x03(\x0b\x32&.A.B.C.TestMessage.MapInt32StringEntry\x12@\n\x10map_int64_string\x18> \x03(\x0b\x32&.A.B.C.TestMessage.MapInt64StringEntry\x12\x42\n\x11map_uint32_string\x18? \x03(\x0b\x32\'.A.B.C.TestMessage.MapUint32StringEntry\x12\x42\n\x11map_uint64_string\x18@ \x03(\x0b\x32\'.A.B.C.TestMessage.MapUint64StringEntry\x12>\n\x0fmap_bool_string\x18\x41 \x03(\x0b\x32%.A.B.C.TestMessage.MapBoolStringEntry\x12\x42\n\x11map_string_string\x18\x42 \x03(\x0b\x32\'.A.B.C.TestMessage.MapStringStringEntry\x12<\n\x0emap_string_msg\x18\x43 \x03(\x0b\x32$.A.B.C.TestMessage.MapStringMsgEntry\x12>\n\x0fmap_string_enum\x18\x44 \x03(\x0b\x32%.A.B.C.TestMessage.MapStringEnumEntry\x12@\n\x10map_string_int32\x18\x45 \x03(\x0b\x32&.A.B.C.TestMessage.MapStringInt32Entry\x12>\n\x0fmap_string_bool\x18\x46 \x03(\x0b\x32%.A.B.C.TestMessage.MapStringBoolEntry\x12\x38\n\x0enested_message\x18P \x01(\x0b\x32 .A.B.C.TestMessage.NestedMessage\x1a\x35\n\x13MapInt32StringEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x35\n\x13MapInt64StringEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x36\n\x14MapUint32StringEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x36\n\x14MapUint64StringEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x34\n\x12MapBoolStringEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x36\n\x14MapStringStringEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aG\n\x11MapStringMsgEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12!\n\x05value\x18\x02 \x01(\x0b\x32\x12.A.B.C.TestMessage:\x02\x38\x01\x1a\x45\n\x12MapStringEnumEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x1e\n\x05value\x18\x02 \x01(\x0e\x32\x0f.A.B.C.TestEnum:\x02\x38\x01\x1a\x35\n\x13MapStringInt32Entry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x34\n\x12MapStringBoolEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x08:\x02\x38\x01\x1a\x1c\n\rNestedMessage\x12\x0b\n\x03\x66oo\x18\x01 \x01(\x05\x42\n\n\x08my_oneof*,\n\x08TestEnum\x12\x0b\n\x07\x44\x65\x66\x61ult\x10\x00\x12\x05\n\x01\x41\x10\x01\x12\x05\n\x01\x42\x10\x02\x12\x05\n\x01\x43\x10\x03\x62\x06proto3" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ + ["A.B.C.TestImportedMessage", "ruby_generated_code_proto2_import.proto"], + ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" end end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." end module A diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb index 44d31969ec..5fb22ac24c 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_code_proto2.proto @@ -5,68 +6,32 @@ require 'google/protobuf' require 'ruby_generated_code_proto2_import_pb' -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("ruby_generated_code_proto2.proto", :syntax => :proto2) do - add_message "A.B.C.TestMessage" do - optional :optional_int32, :int32, 1, default: 1 - optional :optional_int64, :int64, 2, default: 2 - optional :optional_uint32, :uint32, 3, default: 3 - optional :optional_uint64, :uint64, 4, default: 4 - optional :optional_bool, :bool, 5, default: true - optional :optional_double, :double, 6, default: 6 - optional :optional_float, :float, 7, default: 7 - optional :optional_string, :string, 8, default: "default str" - optional :optional_bytes, :bytes, 9, default: "\x00\x01\x02\x40\x66\x75\x62\x61\x72".force_encoding("ASCII-8BIT") - optional :optional_enum, :enum, 10, "A.B.C.TestEnum", default: 1 - optional :optional_msg, :message, 11, "A.B.C.TestMessage" - optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage" - repeated :repeated_int32, :int32, 21 - repeated :repeated_int64, :int64, 22 - repeated :repeated_uint32, :uint32, 23 - repeated :repeated_uint64, :uint64, 24 - repeated :repeated_bool, :bool, 25 - repeated :repeated_double, :double, 26 - repeated :repeated_float, :float, 27 - repeated :repeated_string, :string, 28 - repeated :repeated_bytes, :bytes, 29 - repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum" - repeated :repeated_msg, :message, 31, "A.B.C.TestMessage" - required :required_int32, :int32, 41 - required :required_int64, :int64, 42 - required :required_uint32, :uint32, 43 - required :required_uint64, :uint64, 44 - required :required_bool, :bool, 45 - required :required_double, :double, 46 - required :required_float, :float, 47 - required :required_string, :string, 48 - required :required_bytes, :bytes, 49 - required :required_enum, :enum, 50, "A.B.C.TestEnum" - required :required_msg, :message, 51, "A.B.C.TestMessage" - optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage" - oneof :my_oneof do - optional :oneof_int32, :int32, 61 - optional :oneof_int64, :int64, 62 - optional :oneof_uint32, :uint32, 63 - optional :oneof_uint64, :uint64, 64 - optional :oneof_bool, :bool, 65 - optional :oneof_double, :double, 66 - optional :oneof_float, :float, 67 - optional :oneof_string, :string, 68 - optional :oneof_bytes, :bytes, 69 - optional :oneof_enum, :enum, 70, "A.B.C.TestEnum" - optional :oneof_msg, :message, 71, "A.B.C.TestMessage" - end - end - add_message "A.B.C.TestMessage.NestedMessage" do - optional :foo, :int32, 1 - end - add_enum "A.B.C.TestEnum" do - value :Default, 0 - value :A, 1 - value :B, 2 - value :C, 3 + +descriptor_data = "\n ruby_generated_code_proto2.proto\x12\x05\x41.B.C\x1a\'ruby_generated_code_proto2_import.proto\"\x96\x0b\n\x0bTestMessage\x12\x19\n\x0eoptional_int32\x18\x01 \x01(\x05:\x01\x31\x12\x19\n\x0eoptional_int64\x18\x02 \x01(\x03:\x01\x32\x12\x1a\n\x0foptional_uint32\x18\x03 \x01(\r:\x01\x33\x12\x1a\n\x0foptional_uint64\x18\x04 \x01(\x04:\x01\x34\x12\x1b\n\roptional_bool\x18\x05 \x01(\x08:\x04true\x12\x1a\n\x0foptional_double\x18\x06 \x01(\x01:\x01\x36\x12\x19\n\x0eoptional_float\x18\x07 \x01(\x02:\x01\x37\x12$\n\x0foptional_string\x18\x08 \x01(\t:\x0b\x64\x65\x66\x61ult str\x12*\n\x0eoptional_bytes\x18\t \x01(\x0c:\x12\\000\\001\\002@fubar\x12)\n\roptional_enum\x18\n \x01(\x0e\x32\x0f.A.B.C.TestEnum:\x01\x41\x12(\n\x0coptional_msg\x18\x0b \x01(\x0b\x32\x12.A.B.C.TestMessage\x12>\n\x1aoptional_proto2_submessage\x18\x0c \x01(\x0b\x32\x1a.A.B.C.TestImportedMessage\x12\x16\n\x0erepeated_int32\x18\x15 \x03(\x05\x12\x16\n\x0erepeated_int64\x18\x16 \x03(\x03\x12\x17\n\x0frepeated_uint32\x18\x17 \x03(\r\x12\x17\n\x0frepeated_uint64\x18\x18 \x03(\x04\x12\x15\n\rrepeated_bool\x18\x19 \x03(\x08\x12\x17\n\x0frepeated_double\x18\x1a \x03(\x01\x12\x16\n\x0erepeated_float\x18\x1b \x03(\x02\x12\x17\n\x0frepeated_string\x18\x1c \x03(\t\x12\x16\n\x0erepeated_bytes\x18\x1d \x03(\x0c\x12&\n\rrepeated_enum\x18\x1e \x03(\x0e\x32\x0f.A.B.C.TestEnum\x12(\n\x0crepeated_msg\x18\x1f \x03(\x0b\x32\x12.A.B.C.TestMessage\x12\x16\n\x0erequired_int32\x18) \x02(\x05\x12\x16\n\x0erequired_int64\x18* \x02(\x03\x12\x17\n\x0frequired_uint32\x18+ \x02(\r\x12\x17\n\x0frequired_uint64\x18, \x02(\x04\x12\x15\n\rrequired_bool\x18- \x02(\x08\x12\x17\n\x0frequired_double\x18. \x02(\x01\x12\x16\n\x0erequired_float\x18/ \x02(\x02\x12\x17\n\x0frequired_string\x18\x30 \x02(\t\x12\x16\n\x0erequired_bytes\x18\x31 \x02(\x0c\x12&\n\rrequired_enum\x18\x32 \x02(\x0e\x32\x0f.A.B.C.TestEnum\x12(\n\x0crequired_msg\x18\x33 \x02(\x0b\x32\x12.A.B.C.TestMessage\x12\x15\n\x0boneof_int32\x18= \x01(\x05H\x00\x12\x15\n\x0boneof_int64\x18> \x01(\x03H\x00\x12\x16\n\x0coneof_uint32\x18? \x01(\rH\x00\x12\x16\n\x0coneof_uint64\x18@ \x01(\x04H\x00\x12\x14\n\noneof_bool\x18\x41 \x01(\x08H\x00\x12\x16\n\x0coneof_double\x18\x42 \x01(\x01H\x00\x12\x15\n\x0boneof_float\x18\x43 \x01(\x02H\x00\x12\x16\n\x0coneof_string\x18\x44 \x01(\tH\x00\x12\x15\n\x0boneof_bytes\x18\x45 \x01(\x0cH\x00\x12%\n\noneof_enum\x18\x46 \x01(\x0e\x32\x0f.A.B.C.TestEnumH\x00\x12\'\n\toneof_msg\x18G \x01(\x0b\x32\x12.A.B.C.TestMessageH\x00\x12\x38\n\x0enested_message\x18P \x01(\x0b\x32 .A.B.C.TestMessage.NestedMessage\x1a\x1c\n\rNestedMessage\x12\x0b\n\x03\x66oo\x18\x01 \x01(\x05\x42\n\n\x08my_oneof*,\n\x08TestEnum\x12\x0b\n\x07\x44\x65\x66\x61ult\x10\x00\x12\x05\n\x01\x41\x10\x01\x12\x05\n\x01\x42\x10\x02\x12\x05\n\x01\x43\x10\x03" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ + ["A.B.C.TestImportedMessage", "ruby_generated_code_proto2_import.proto"], + ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" end end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." end module A diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb index cdbbe891bc..9fdfd23d3f 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb @@ -1,14 +1,34 @@ +# frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_pkg_explicit_legacy.proto require 'google/protobuf' -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("ruby_generated_pkg_explicit_legacy.proto", :syntax => :proto3) do - add_message "one.two.a_three.and.Four" do - optional :another_string, :string, 1 + +descriptor_data = "\n(ruby_generated_pkg_explicit_legacy.proto\x12\x13one.two.a_three.and\"\x1e\n\x04\x46our\x12\x16\n\x0e\x61nother_string\x18\x01 \x01(\tB\x0b\xea\x02\x08\x41\x41.BB.CCb\x06proto3" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ + ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" end end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." end module AA diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb index e6d47011e8..b6092082ac 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb @@ -1,14 +1,34 @@ +# frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_pkg_explicit.proto require 'google/protobuf' -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("ruby_generated_pkg_explicit.proto", :syntax => :proto3) do - add_message "one.two.a_three.Four" do - optional :a_string, :string, 1 + +descriptor_data = "\n!ruby_generated_pkg_explicit.proto\x12\x0fone.two.a_three\"\x18\n\x04\x46our\x12\x10\n\x08\x61_string\x18\x01 \x01(\tB\n\xea\x02\x07\x41::B::Cb\x06proto3" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ + ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" end end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." end module A diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb index 1ac0ef7ad0..062800a61d 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb +++ b/src/google/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb @@ -1,14 +1,34 @@ +# frozen_string_literal: true # Generated by the protocol buffer compiler. DO NOT EDIT! # source: ruby_generated_pkg_implicit.proto require 'google/protobuf' -Google::Protobuf::DescriptorPool.generated_pool.build do - add_file("ruby_generated_pkg_implicit.proto", :syntax => :proto3) do - add_message "one.two.a_three.Four" do - optional :a_string, :string, 1 + +descriptor_data = "\n!ruby_generated_pkg_implicit.proto\x12\x0fone.two.a_three\"\x18\n\x04\x46our\x12\x10\n\x08\x61_string\x18\x01 \x01(\tb\x06proto3" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ + ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" end end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." end module One diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 625c5004d4..70a6a837d1 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -35,7 +35,9 @@ #include #include "google/protobuf/compiler/code_generator.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/absl_log.h" +#include "absl/strings/escaping.h" #include "google/protobuf/compiler/plugin.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -54,9 +56,6 @@ std::string NumberToString(numeric_type value); std::string GetRequireName(absl::string_view proto_file); std::string LabelForField(FieldDescriptor* field); std::string TypeName(FieldDescriptor* field); -bool GenerateMessage(const Descriptor* message, io::Printer* printer, - std::string* error); -void GenerateEnum(const EnumDescriptor* en, io::Printer* printer); void GenerateMessageAssignment(absl::string_view prefix, const Descriptor* message, io::Printer* printer); void GenerateEnumAssignment(absl::string_view prefix, const EnumDescriptor* en, @@ -79,238 +78,6 @@ std::string GetOutputFilename(absl::string_view proto_file) { return absl::StrCat(GetRequireName(proto_file), ".rb"); } -std::string LabelForField(const FieldDescriptor* field) { - if (FieldDescriptorLegacy(field).has_optional_keyword() && - field->containing_oneof() != nullptr) { - return "proto3_optional"; - } - switch (field->label()) { - case FieldDescriptor::LABEL_OPTIONAL: return "optional"; - case FieldDescriptor::LABEL_REQUIRED: return "required"; - case FieldDescriptor::LABEL_REPEATED: return "repeated"; - default: assert(false); return ""; - } -} - -std::string TypeName(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32: return "int32"; - case FieldDescriptor::TYPE_INT64: return "int64"; - case FieldDescriptor::TYPE_UINT32: return "uint32"; - case FieldDescriptor::TYPE_UINT64: return "uint64"; - case FieldDescriptor::TYPE_SINT32: return "sint32"; - case FieldDescriptor::TYPE_SINT64: return "sint64"; - case FieldDescriptor::TYPE_FIXED32: return "fixed32"; - case FieldDescriptor::TYPE_FIXED64: return "fixed64"; - case FieldDescriptor::TYPE_SFIXED32: return "sfixed32"; - case FieldDescriptor::TYPE_SFIXED64: return "sfixed64"; - case FieldDescriptor::TYPE_DOUBLE: return "double"; - case FieldDescriptor::TYPE_FLOAT: return "float"; - case FieldDescriptor::TYPE_BOOL: return "bool"; - case FieldDescriptor::TYPE_ENUM: return "enum"; - case FieldDescriptor::TYPE_STRING: return "string"; - case FieldDescriptor::TYPE_BYTES: return "bytes"; - case FieldDescriptor::TYPE_MESSAGE: return "message"; - case FieldDescriptor::TYPE_GROUP: return "group"; - default: assert(false); return ""; - } -} - -std::string StringifySyntax(FileDescriptorLegacy::Syntax syntax) { - switch (syntax) { - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: - return "proto2"; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: - return "proto3"; - case FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN: - default: - ABSL_LOG(FATAL) << "Unsupported syntax; this generator only supports " - "proto2 and proto3 syntax."; - return ""; - } -} - -std::string DefaultValueForField(const FieldDescriptor* field) { - switch(field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return NumberToString(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_INT64: - return NumberToString(field->default_value_int64()); - case FieldDescriptor::CPPTYPE_UINT32: - return NumberToString(field->default_value_uint32()); - case FieldDescriptor::CPPTYPE_UINT64: - return NumberToString(field->default_value_uint64()); - case FieldDescriptor::CPPTYPE_FLOAT: - return NumberToString(field->default_value_float()); - case FieldDescriptor::CPPTYPE_DOUBLE: - return NumberToString(field->default_value_double()); - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "true" : "false"; - case FieldDescriptor::CPPTYPE_ENUM: - return NumberToString(field->default_value_enum()->number()); - case FieldDescriptor::CPPTYPE_STRING: { - std::ostringstream os; - std::string default_str = field->default_value_string(); - - if (field->type() == FieldDescriptor::TYPE_STRING) { - os << "\"" << default_str << "\""; - } else if (field->type() == FieldDescriptor::TYPE_BYTES) { - os << "\""; - - os.fill('0'); - for (int i = 0; i < default_str.length(); ++i) { - // Write the hex form of each byte. - os << "\\x" << std::hex << std::setw(2) - << ((uint16_t)((unsigned char)default_str.at(i))); - } - os << "\".force_encoding(\"ASCII-8BIT\")"; - } - - return os.str(); - } - default: assert(false); return ""; - } -} - -void GenerateField(const FieldDescriptor* field, io::Printer* printer) { - if (field->is_map()) { - const FieldDescriptor* key_field = - field->message_type()->FindFieldByNumber(1); - const FieldDescriptor* value_field = - field->message_type()->FindFieldByNumber(2); - - printer->Print( - "map :$name$, :$key_type$, :$value_type$, $number$", - "name", field->name(), - "key_type", TypeName(key_field), - "value_type", TypeName(value_field), - "number", NumberToString(field->number())); - - if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - ", \"$subtype$\"\n", - "subtype", value_field->message_type()->full_name()); - } else if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - printer->Print( - ", \"$subtype$\"\n", - "subtype", value_field->enum_type()->full_name()); - } else { - printer->Print("\n"); - } - } else { - - printer->Print( - "$label$ :$name$, ", - "label", LabelForField(field), - "name", field->name()); - printer->Print( - ":$type$, $number$", - "type", TypeName(field), - "number", NumberToString(field->number())); - - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - ", \"$subtype$\"", - "subtype", field->message_type()->full_name()); - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - printer->Print( - ", \"$subtype$\"", - "subtype", field->enum_type()->full_name()); - } - - if (field->has_default_value()) { - printer->Print(", default: $default$", "default", - DefaultValueForField(field)); - } - - if (field->has_json_name()) { - printer->Print(", json_name: \"$json_name$\"", "json_name", - field->json_name()); - } - - printer->Print("\n"); - } -} - -void GenerateOneof(const OneofDescriptor* oneof, io::Printer* printer) { - printer->Print( - "oneof :$name$ do\n", - "name", oneof->name()); - printer->Indent(); - - for (int i = 0; i < oneof->field_count(); i++) { - const FieldDescriptor* field = oneof->field(i); - GenerateField(field, printer); - } - - printer->Outdent(); - printer->Print("end\n"); -} - -bool GenerateMessage(const Descriptor* message, io::Printer* printer, - std::string* error) { - if (message->extension_range_count() > 0 || message->extension_count() > 0) { - ABSL_LOG(WARNING) - << "Extensions are not yet supported for proto2 .proto files."; - } - - // Don't generate MapEntry messages -- we use the Ruby extension's native - // support for map fields instead. - if (message->options().map_entry()) { - return true; - } - - printer->Print( - "add_message \"$name$\" do\n", - "name", message->full_name()); - printer->Indent(); - - for (int i = 0; i < message->field_count(); i++) { - const FieldDescriptor* field = message->field(i); - if (!field->real_containing_oneof()) { - GenerateField(field, printer); - } - } - - for (int i = 0; i < message->real_oneof_decl_count(); i++) { - const OneofDescriptor* oneof = message->oneof_decl(i); - GenerateOneof(oneof, printer); - } - - printer->Outdent(); - printer->Print("end\n"); - - for (int i = 0; i < message->nested_type_count(); i++) { - if (!GenerateMessage(message->nested_type(i), printer, error)) { - return false; - } - } - for (int i = 0; i < message->enum_type_count(); i++) { - GenerateEnum(message->enum_type(i), printer); - } - - return true; -} - -void GenerateEnum(const EnumDescriptor* en, io::Printer* printer) { - printer->Print( - "add_enum \"$name$\" do\n", - "name", en->full_name()); - printer->Indent(); - - for (int i = 0; i < en->value_count(); i++) { - const EnumValueDescriptor* value = en->value(i); - printer->Print( - "value :$name$, $number$\n", - "name", value->name(), - "number", NumberToString(value->number())); - } - - printer->Outdent(); - printer->Print( - "end\n"); -} - // Locale-agnostic utility functions. bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; } @@ -470,47 +237,91 @@ void EndPackageModules(int levels, io::Printer* printer) { } } -bool GenerateDslDescriptor(const FileDescriptor* file, io::Printer* printer, - std::string* error) { - printer->Print("Google::Protobuf::DescriptorPool.generated_pool.build do\n"); - printer->Indent(); - printer->Print("add_file(\"$filename$\", :syntax => :$syntax$) do\n", - "filename", file->name(), "syntax", - StringifySyntax(FileDescriptorLegacy(file).syntax())); - printer->Indent(); +std::string SerializedDescriptor(const FileDescriptor* file) { + FileDescriptorProto file_proto; + file->CopyTo(&file_proto); + std::string file_data; + file_proto.SerializeToString(&file_data); + return file_data; +} + +template +void ForEachField(const Descriptor* d, F&& func) { + for (int i = 0; i < d->field_count(); i++) { + func(d->field(i)); + } + for (int i = 0; i < d->nested_type_count(); i++) { + ForEachField(d->nested_type(i), func); + } +} + +template +void ForEachField(const FileDescriptor* file, F&& func) { for (int i = 0; i < file->message_type_count(); i++) { - if (!GenerateMessage(file->message_type(i), printer, error)) { - return false; - } + ForEachField(file->message_type(i), func); } - for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnum(file->enum_type(i), printer); + for (int i = 0; i < file->extension_count(); i++) { + func(file->extension(i)); } - printer->Outdent(); - printer->Print("end\n"); - printer->Outdent(); - printer->Print( - "end\n\n"); - return true; } -bool GenerateBinaryDescriptor(const FileDescriptor* file, io::Printer* printer, +std::string DumpImportList(const FileDescriptor* file) { + // For each import, find a symbol that comes from that file. + absl::flat_hash_set seen{file}; + std::string ret; + ForEachField(file, [&](const FieldDescriptor* field) { + if (!field->message_type()) return; + const FileDescriptor* f = field->message_type()->file(); + if (!seen.insert(f).second) return; + absl::StrAppend(&ret, " [\"", field->message_type()->full_name(), + "\", \"", f->name(), "\"],\n"); + }); + return ret; +} + +void GenerateBinaryDescriptor(const FileDescriptor* file, io::Printer* printer, std::string* error) { - printer->Print( - R"(descriptor_data = File.binread(__FILE__).split("\n__END__\n", 2)[1])"); - printer->Print( - "\nGoogle::Protobuf::DescriptorPool.generated_pool.add_serialized_file(" - "descriptor_data)\n\n"); - return true; + printer->Print(R"( +descriptor_data = "$descriptor_data$" + +pool = Google::Protobuf::DescriptorPool.generated_pool + +begin + pool.add_serialized_file(descriptor_data) +rescue TypeError => e + # Compatibility code: will be removed in the next major version. + require 'google/protobuf/descriptor_pb' + parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data) + parsed.clear_dependency + serialized = parsed.class.encode(parsed) + file = pool.add_serialized_file(serialized) + warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}" + imports = [ +$imports$ ] + imports.each do |type_name, expected_filename| + import_file = pool.lookup(type_name).file_descriptor + if import_file.name != expected_filename + warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}" + end + end + warn "Each proto file must use a consistent fully-qualified name." + warn "This will become an error in the next major version." +end + +)", + "descriptor_data", + absl::CHexEscape(SerializedDescriptor(file)), "imports", + DumpImportList(file)); } bool GenerateFile(const FileDescriptor* file, io::Printer* printer, std::string* error) { printer->Print( - "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "# source: $filename$\n" - "\n", - "filename", file->name()); + "# frozen_string_literal: true\n" + "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "# source: $filename$\n" + "\n", + "filename", file->name()); printer->Print("require 'google/protobuf'\n\n"); @@ -526,13 +337,7 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, ABSL_LOG(WARNING) << "Extensions are not yet supported in Ruby."; } - bool use_raw_descriptor = file->name() == "google/protobuf/descriptor.proto"; - - if (use_raw_descriptor) { - GenerateBinaryDescriptor(file, printer, error); - } else { - GenerateDslDescriptor(file, printer, error); - } + GenerateBinaryDescriptor(file, printer, error); int levels = GeneratePackageModules(file, printer); for (int i = 0; i < file->message_type_count(); i++) { @@ -543,14 +348,6 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, } EndPackageModules(levels, printer); - if (use_raw_descriptor) { - printer->Print("\n__END__\n"); - FileDescriptorProto file_proto; - file->CopyTo(&file_proto); - std::string file_data; - file_proto.SerializeToString(&file_data); - printer->Print("$raw_descriptor$", "raw_descriptor", file_data); - } return true; }