-
Notifications
You must be signed in to change notification settings - Fork 0
Generated Cpp API
Every generated message is templated on a runtime configuration:
template <class Config = ::protocyte::DefaultConfig>
struct Message;Generated messages are move-only. Ordinary C++ copying is deleted because it cannot report allocation failure.
Construction binds a non-owning context and does not allocate:
protocyte::DefaultConfig::Context ctx {
protocyte::hosted_allocator(),
protocyte::Limits {},
};
auto message = demo::Sample<>::create(ctx);The context and allocator state must outlive the message.
Primitive scalar setters return void. Operations that can fail return [[nodiscard]] values:
-
protocyte::Status; -
protocyte::Result<T>; -
protocyte::Result<T&>for reference-valued operations.
Check a result before reading its value:
const auto parsed = demo::Sample<>::parse(ctx, bytes);
if (!parsed) {
const auto &error = parsed.error();
// error.code, error.offset, error.field_number
}
const auto &message = *parsed;Access .error() only after a false status check.
Generated messages expose:
-
create(ctx); -
parse(ctx, reader)andparse(ctx, input_bytes); -
parse(reader, output); -
merge_from(reader); -
serialize(writer)andserialize(output_bytes); -
encoded_size(); -
copy_from(source)andcopy_from(source, staging_message); -
clone()andclone(output); - protobuf-derived field accessors.
The exact accessor set depends on field kind and presence:
- immutable accessors such as
value(); -
set_*()for scalar values; -
has_*()for fields with presence; -
clear_*()where clearing is meaningful; -
mutable_*()for mutable strings, bytes, messages, and containers; -
ensure_*()for fallible nested-message creation.
Repeated fields expose their configured vector surface. Maps expose their configured map surface. Oneofs expose a case discriminator and only commit case changes after the incoming value is ready.
parse(ctx, input) accepts protocyte::Span<const protocyte::u8>:
const auto parsed = demo::Sample<>::parse(ctx, encoded);Compatible lvalue ranges such as arrays, std::array, std::vector, and std::span convert to the dynamic span automatically.
The overload creates a SliceReader and delegates to the reader-based parser.
Avoid a complete outer-message temporary:
demo::Sample<> output {ctx};
protocyte::SliceReader reader {encoded.data(), encoded.size()};
const auto status = demo::Sample<>::parse(reader, output);
if (!status) {
// output is empty and remains bound to ctx
}On failure, the output is reset to an empty message with its original destination context.
merge_from(reader) follows protobuf merge semantics.
Successfully parsed field occurrences remain committed if a later occurrence fails. The failing occurrence itself does not change visible state:
- singular nested messages commit after the complete occurrence parses;
- oneofs switch cases only after successful parsing;
- repeated fields append only complete elements;
- malformed packed payloads append no decoded prefix;
- maps insert only complete entries.
See Errors, Limits, and Wire Behavior.
Compute the required size:
const auto size = message.encoded_size();
if (!size) {
return handle(size.error());
}Serialize to a mutable contiguous range:
std::vector<protocyte::u8> encoded(*size);
const auto written = message.serialize(encoded);This overload returns the number of bytes written. It preflights the encoded size, so an undersized contiguous buffer returns ErrorCode::size_limit without modifying the buffer.
serialize(writer) is incremental rather than transactional. A custom writer failure can leave bytes from earlier successful calls committed. Stage output when all-or-nothing publication is required.
Generated messages use explicit fallible deep copies:
const auto status = destination.copy_from(source);
const auto cloned = source.clone();Caller-controlled variants avoid an internal full-message temporary:
demo::Sample<> staging {ctx};
const auto copy_status = destination.copy_from(source, staging);
demo::Sample<> output {ctx};
const auto clone_status = source.clone(output);copy_from(source, staging) is transactional for the destination. On success, staging remains valid but moved-from and must not alias either operand.
clone() uses the source context. clone(output) retains the context already bound to output.
Generated immutable string accessors return protocyte::StringView.
By default:
using StringView = protocyte::Span<const char>;Hosted targets can enable std::string_view interoperability:
target_compile_definitions(
demo_proto
PUBLIC PROTOCYTE_ENABLE_STD_STRING_VIEW=1
)The definition changes public signatures, so all translation units in that target graph must use the same value.
Unknown-field preservation is disabled by default:
struct ForwardCompatibleConfig : protocyte::DefaultConfig {
static constexpr bool preserve_unknown_fields = true;
};Enabled messages expose:
-
unknown_fields(); -
unknown_field_count(); -
unknown_field_bytes(); -
clear_unknown_fields(); -
mutable_unknown_fields().
Unknown occurrences retain encounter order as canonical protobuf bytes. Parsing and reserialization do not promise byte-identical forwarding.
The disabled storage specialization adds no message object footprint.
Reflection tables are emitted only when PROTOCYTE_ENABLE_REFLECTION is nonzero:
target_compile_definitions(
demo_proto
PUBLIC PROTOCYTE_ENABLE_REFLECTION=1
)PUBLIC visibility is required so generated sources and consumers see the same declaration surface.
On Windows, protocyte_add_proto_library(TYPE SHARED) gives reflection data a target-unique import/export macro. Direct generator users that build a DLL must manage visibility themselves.
Each generated message receives an externally linked std::array<protocyte::ReflectionFieldInfo, N> in its package's protocyte_reflection namespace.
Legal schema declarations that collide with generated helper names or internal template parameter spellings are remapped deterministically. The protobuf-derived type remains usable without emitting invalid C++.
Cross-file collisions that cannot be renamed consistently are rejected. See Plugin Parameters.
Repository · Releases · Issues · Apache License 2.0
Canonical source: docs/wiki/