pw_protobuf: Fixed bug when using proto package without prefix pw.* When generating code using the pw protobuf plugin if the .proto does not contain 'package pw.*;' then namespace pw is not added. This results in errors around span<> not being found. Changing all strings in the code generator from regex 'span<(.*)>' to 'std::span<$1>' solves this problem. A regression test proto has been added to prevent this problem in future. Change-Id: I5fa2f750a3ff562b7e28da667b8148a04a6fc579 Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/12620 Reviewed-by: Wyatt Hepler <hepler@google.com> Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_protobuf/BUILD.gn b/pw_protobuf/BUILD.gn index a34c0c8..5a4e800 100644 --- a/pw_protobuf/BUILD.gn +++ b/pw_protobuf/BUILD.gn
@@ -101,6 +101,7 @@ "pw_protobuf_protos/test_protos/full_test.proto", "pw_protobuf_protos/test_protos/imported.proto", "pw_protobuf_protos/test_protos/importer.proto", + "pw_protobuf_protos/test_protos/non_pw_package.proto", "pw_protobuf_protos/test_protos/proto2.proto", "pw_protobuf_protos/test_protos/repeated.proto", ]
diff --git a/pw_protobuf/codegen_test.cc b/pw_protobuf/codegen_test.cc index 273b170..1001a86 100644 --- a/pw_protobuf/codegen_test.cc +++ b/pw_protobuf/codegen_test.cc
@@ -11,6 +11,7 @@ // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. +#include <span> #include "gtest/gtest.h" #include "pw_protobuf/encoder.h" @@ -24,6 +25,7 @@ // low-level encoder. #include "pw_protobuf_protos/test_protos/full_test.pwpb.h" #include "pw_protobuf_protos/test_protos/importer.pwpb.h" +#include "pw_protobuf_protos/test_protos/non_pw_package.pwpb.h" #include "pw_protobuf_protos/test_protos/proto2.pwpb.h" #include "pw_protobuf_protos/test_protos/repeated.pwpb.h" @@ -295,5 +297,18 @@ EXPECT_EQ(encoder.Encode(&proto), Status::OK); } +TEST(Codegen, NonPigweedPackage) { + using namespace non::pigweed::package::name; + std::byte encode_buffer[64]; + std::array<const int64_t, 2> repeated = {0, 1}; + NestedEncoder<1, 2> encoder(encode_buffer); + Packed::Encoder packed(&encoder); + packed.WriteRep(std::span<const int64_t>(repeated)); + packed.WritePacked("packed"); + + span<const std::byte> proto; + EXPECT_EQ(encoder.Encode(&proto), Status::OK); +} + } // namespace } // namespace pw::protobuf
diff --git a/pw_protobuf/pw_protobuf_protos/test_protos/non_pw_package.proto b/pw_protobuf/pw_protobuf_protos/test_protos/non_pw_package.proto new file mode 100644 index 0000000..ddc11ff --- /dev/null +++ b/pw_protobuf/pw_protobuf_protos/test_protos/non_pw_package.proto
@@ -0,0 +1,26 @@ +// Copyright 2020 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +syntax = "proto3"; + +// Test that non-pigweed packages work as expected when generating code. Pigweed +// packages start with `package pw.*` which results in some implicit +// namespacing in generated code. +package non.pigweed.package.name; + +// Packed has both a repeated and length delimited messaged type. This should +// result in a span being generated in the corresponding *pwpb.h file. +message Packed { + string packed = 1; + repeated int64 rep = 2; +}
diff --git a/pw_protobuf/py/pw_protobuf/codegen_pwpb.py b/pw_protobuf/py/pw_protobuf/codegen_pwpb.py index 5fb6661..b9760fa 100644 --- a/pw_protobuf/py/pw_protobuf/codegen_pwpb.py +++ b/pw_protobuf/py/pw_protobuf/codegen_pwpb.py
@@ -207,7 +207,7 @@ class PackedDoubleMethod(PackedMethod): """Method which writes a packed list of doubles.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const double>', 'values')] + return [('std::span<const double>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedDouble' @@ -225,7 +225,7 @@ class PackedFloatMethod(PackedMethod): """Method which writes a packed list of floats.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const float>', 'values')] + return [('std::span<const float>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedFloat' @@ -243,7 +243,7 @@ class PackedInt32Method(PackedMethod): """Method which writes a packed list of int32.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int32_t>', 'values')] + return [('std::span<const int32_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedInt32' @@ -261,7 +261,7 @@ class PackedSint32Method(PackedMethod): """Method which writes a packed list of sint32.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int32_t>', 'values')] + return [('std::span<const int32_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedSint32' @@ -279,7 +279,7 @@ class PackedSfixed32Method(PackedMethod): """Method which writes a packed list of sfixed32.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int32_t>', 'values')] + return [('std::span<const int32_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedSfixed32' @@ -297,7 +297,7 @@ class PackedInt64Method(PackedMethod): """Method which writes a proto int64 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int64_t>', 'values')] + return [('std::span<const int64_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedInt64' @@ -315,7 +315,7 @@ class PackedSint64Method(PackedMethod): """Method which writes a proto sint64 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int64_t>', 'values')] + return [('std::span<const int64_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedSint64' @@ -333,7 +333,7 @@ class PackedSfixed64Method(PackedMethod): """Method which writes a proto sfixed64 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const int64_t>', 'values')] + return [('std::span<const int64_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedSfixed4' @@ -351,7 +351,7 @@ class PackedUint32Method(PackedMethod): """Method which writes a proto uint32 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const uint32_t>', 'values')] + return [('std::span<const uint32_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedUint32' @@ -369,7 +369,7 @@ class PackedFixed32Method(PackedMethod): """Method which writes a proto fixed32 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const uint32_t>', 'values')] + return [('std::span<const uint32_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedFixed32' @@ -387,7 +387,7 @@ class PackedUint64Method(PackedMethod): """Method which writes a proto uint64 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const uint64_t>', 'values')] + return [('std::span<const uint64_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedUint64' @@ -405,7 +405,7 @@ class PackedFixed64Method(PackedMethod): """Method which writes a proto fixed64 value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const uint64_t>', 'values')] + return [('std::span<const uint64_t>', 'values')] def _encoder_fn(self) -> str: return 'WritePackedFixed64' @@ -423,7 +423,7 @@ class BytesMethod(WriteMethod): """Method which writes a proto bytes value.""" def params(self) -> List[Tuple[str, str]]: - return [('span<const std::byte>', 'value')] + return [('std::span<const std::byte>', 'value')] def _encoder_fn(self) -> str: return 'WriteBytes' @@ -682,7 +682,8 @@ output.write_line(f'// on {datetime.now()}') output.write_line('#pragma once\n') output.write_line('#include <cstddef>') - output.write_line('#include <cstdint>\n') + output.write_line('#include <cstdint>') + output.write_line('#include <span>\n') output.write_line('#include "pw_protobuf/codegen.h"') for imported_file in file_descriptor_proto.dependency: