diff --git a/rust/cpp.rs b/rust/cpp.rs index deac9d951402..9b683bbb22e8 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -47,6 +47,7 @@ use std::ptr::{self, NonNull}; /// dropped. /// /// Note that this type is neither `Sync` nor `Send`. +#[derive(Debug)] pub struct Arena { #[allow(dead_code)] ptr: NonNull, diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index af18fbe4d095..b33b51a1e0ef 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -225,3 +225,13 @@ fn test_optional_bytes_accessors() { msg.optional_bytes_set(Some(b"")); assert_eq!(msg.optional_bytes().unwrap(), b""); } + +#[test] +#[should_panic = "b/285309454"] +#[allow(unreachable_code)] +fn test_singular_msg_field() { + let msg = TestAllTypes::new(); + // TODO("b/285309454"): fetch the inner integer `bb` + // call should look like msg.optional_nested_message().bb() + match msg.optional_nested_message() {} +} diff --git a/rust/upb.rs b/rust/upb.rs index e1e795a9d42d..204d3dbf86bc 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -61,6 +61,7 @@ pub struct RawArenaData { /// dropped. /// /// Note that this type is neither `Sync` nor `Send`. +#[derive(Debug)] pub struct Arena { // Safety invariant: this must always be a valid arena raw: RawArena, diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel index 96ee032f09d6..6936acb8c019 100644 --- a/src/google/protobuf/compiler/rust/BUILD.bazel +++ b/src/google/protobuf/compiler/rust/BUILD.bazel @@ -51,6 +51,7 @@ cc_library( srcs = [ "accessors/accessors.cc", "accessors/singular_bytes.cc", + "accessors/singular_message.cc", "accessors/singular_scalar.cc", ], hdrs = ["accessors/accessors.h"], diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc index 627afd272904..728dba2f578e 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.cc +++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc @@ -65,6 +65,9 @@ std::unique_ptr AccessorGenerator::For( case FieldDescriptor::TYPE_BYTES: if (field.desc().is_repeated()) return nullptr; return ForSingularBytes(field); + case FieldDescriptor::TYPE_MESSAGE: + if (field.desc().is_repeated()) return nullptr; + return ForSingularMessage(field); default: return nullptr; diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.h b/src/google/protobuf/compiler/rust/accessors/accessors.h index baa80c0a9fbe..1b4eb7b13f64 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.h +++ b/src/google/protobuf/compiler/rust/accessors/accessors.h @@ -90,6 +90,8 @@ class AccessorGenerator { Context field); static std::unique_ptr ForSingularBytes( Context field); + static std::unique_ptr ForSingularMessage( + Context field); }; } // namespace rust diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc new file mode 100644 index 000000000000..f10221f95037 --- /dev/null +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google LLC. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/rust/accessors/accessors.h" +#include "google/protobuf/compiler/rust/context.h" +#include "google/protobuf/compiler/rust/naming.h" +#include "google/protobuf/descriptor.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { +namespace { +class SingularMessage final : public AccessorGenerator { + public: + ~SingularMessage() override = default; + + void InMsgImpl(Context field) const override { + field.Emit( + { + {"field", field.desc().name()}, + }, + R"rs( + // inMsgImpl + pub fn $field$(&self) -> std::convert::Infallible { + todo!("b/285309454") + } + )rs"); + } + + void InExternC(Context field) const override { + field.Emit({}, + R"rs( + // inExternC + )rs"); + } + + void InThunkCc(Context field) const override { + field.Emit({}, + R"cc( + // inThunkCC + )cc"); + } +}; +} // namespace + +std::unique_ptr AccessorGenerator::ForSingularMessage( + Context field) { + return std::make_unique(); +} +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 3de5102edeb7..6468f4bde1ff 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -288,10 +288,61 @@ void MessageGenerator::GenerateRs(Context msg) { }, R"rs( #[allow(non_camel_case_types)] + #[derive(Debug)] pub struct $Msg$ { $Msg.fields$ } + unsafe impl Sync for $Msg$ {} + unsafe impl Sync for $Msg$View<'_> {} + unsafe impl Send for $Msg$View<'_> {} + + impl $pb$::Proxied for $Msg$ { + type View<'a> = $Msg$View<'a>; + type Mut<'a> = $Msg$Mut<'a>; + } + + #[derive(Debug, Copy, Clone)] + pub struct $Msg$View<'a> { + msg: $NonNull$, + _phantom: std::marker::PhantomData<&'a ()>, + } + + impl<'a> $pb$::ViewProxy<'a> for $Msg$View<'a> { + type Proxied = $Msg$; + + fn as_view(&self) -> $pb$::View<'a, $Msg$> { + todo!("b/285309454") + } + fn into_view<'shorter>(self) -> $pb$::View<'shorter, $Msg$> where 'a: 'shorter { todo!("b/285309454") } + } + + impl<'a> $pb$::SettableValue<$Msg$> for $Msg$View<'a> { + fn set_on(self, _private: $pb$::__internal::Private, _mutator: $pb$::Mut<$Msg$>) { + todo!("b/285309454") + } + } + + #[derive(Debug)] + pub struct $Msg$Mut<'a> { + _phantom: std::marker::PhantomData<&'a mut ()>, + } + + impl<'a> $pb$::MutProxy<'a> for $Msg$Mut<'a> { + fn as_mut(&mut self) -> $pb$::Mut<'_, $Msg$> { + todo!("b/285309454") + } + fn into_mut<'shorter>(self) -> $pb$::Mut<'shorter, $Msg$> where 'a : 'shorter { todo!("b/285309454") } + } + + impl<'a> $pb$::ViewProxy<'a> for $Msg$Mut<'a> { + type Proxied = $Msg$; + fn as_view(&self) -> $pb$::View<'_, $Msg$> { + todo!("b/285309454") + } + fn into_view<'shorter>(self) -> $pb$::View<'shorter, $Msg$> where 'a: 'shorter { todo!("b/285309454") } + } + impl $Msg$ { pub fn new() -> Self { $Msg::new$