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: