blob: b0066d38e144add9970f22e15984b01d4445ec7c [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package codegen
const fragmentProtocolTmpl = `
{{- define "ProtocolForwardDeclaration" }}
{{ EnsureNamespace . }}
class {{ .Name }};
{{- end }}
{{- define "ForwardMessageParamsUnwrapTypedChannels" -}}
{{- range $index, $param := . -}}
{{- if $index }}, {{ end -}} std::move(
{{- if or (eq .Type.Kind TypeKinds.Protocol) (eq .Type.Kind TypeKinds.Request) -}}
{{ $param.Name }}.channel()
{{- else -}}
{{ $param.Name }}
{{- end -}}
)
{{- end -}}
{{- end }}
{{- define "ClientAllocationComment" -}}
{{- if SyncCallTotalStackSize . }} Allocates {{ SyncCallTotalStackSize . }} bytes of {{ "" }}
{{- if not .Request.ClientAllocation.IsStack -}} response {{- else -}}
{{- if not .Response.ClientAllocation.IsStack -}} request {{- else -}} message {{- end -}}
{{- end }} buffer on the stack. {{- end }}
{{- if and .Request.ClientAllocation.IsStack .Response.ClientAllocation.IsStack -}}
{{ "" }} No heap allocation necessary.
{{- else }}
{{- if not .Request.ClientAllocation.IsStack }} Request is heap-allocated. {{- end }}
{{- if not .Response.ClientAllocation.IsStack }} Response is heap-allocated. {{- end }}
{{- end }}
{{- end }}
{{- define "ProtocolDeclaration" }}
{{- $protocol := . }}
{{ "" }}
{{- range .Methods }}
{{ EnsureNamespace .Request.WireCodingTable }}
extern "C" const fidl_type_t {{ .Request.WireCodingTable.Name }};
{{ EnsureNamespace .Response.WireCodingTable }}
extern "C" const fidl_type_t {{ .Response.WireCodingTable.Name }};
{{- end }}
{{ "" }}
{{ EnsureNamespace . }}
{{- .Docs }}
class {{ .Name }} final {
{{ .Name }}() = delete;
public:
{{- range .Methods }}
{{- .Docs }}
class {{ .Marker.Self }} final {
{{ .Marker.Self }}() = delete;
};
{{- end }}
};
{{- template "ProtocolDetailsDeclaration" . }}
{{- template "ProtocolDispatcherDeclaration" . }}
{{- range .Methods }}
{{- if .HasRequest }}
{{- template "MethodRequestDeclaration" . }}
{{- end }}
{{- if .HasResponse }}
{{- template "MethodResponseDeclaration" . }}
{{- end }}
{{- end }}
{{- range .ClientMethods -}}
{{- template "MethodResultDeclaration" . }}
{{- template "MethodUnownedResultDeclaration" . }}
{{- end }}
{{- EnsureNamespace "::" }}
// Methods to make a sync FIDL call directly on an unowned channel or a
// const reference to a |fidl::ClientEnd<{{ .WireType }}>|,
// avoiding setting up a client.
template<>
class {{ .WireCaller }} final {
public:
explicit {{ .WireCaller.Self }}(::fidl::UnownedClientEnd<{{ . }}> client_end) :
client_end_(client_end) {}
{{ "" }}
{{- /* Client-calling functions do not apply to events. */}}
{{- range .ClientMethods -}}
{{- .Docs }}
//{{ template "ClientAllocationComment" . }}
static {{ .WireResult }} {{ .Name }}(
::fidl::UnownedClientEnd<{{ .Protocol }}> _client_end
{{- .RequestArgs | CalleeCommaParams }}) {
return {{ .WireResult }}(_client_end
{{- .RequestArgs | ForwardCommaParams -}}
);
}
{{- .Docs }}
//{{ template "ClientAllocationComment" . }}
{{ .WireResult }} {{ .Name }}({{- .RequestArgs | CalleeParams }}) && {
return {{ .WireResult }}(client_end_
{{- .RequestArgs | ForwardCommaParams -}}
);
}
{{ "" }}
{{- if or .RequestArgs .ResponseArgs }}
{{- .Docs }}
// Caller provides the backing storage for FIDL message via request and response buffers.
static {{ .WireUnownedResult }} {{ .Name }}({{ template "StaticCallSyncRequestCallerAllocateMethodArguments" . }}) {
return {{ .WireUnownedResult }}(_client_end
{{- if .RequestArgs -}}
, _request_buffer.data, _request_buffer.capacity
{{- end -}}
{{- .RequestArgs | ForwardCommaParams -}}
{{- if .HasResponse -}}
, _response_buffer.data, _response_buffer.capacity
{{- end -}});
}
{{- .Docs }}
// Caller provides the backing storage for FIDL message via request and response buffers.
{{ .WireUnownedResult }} {{ .Name }}({{ template "SyncRequestCallerAllocateMethodArguments" . }}) && {
return {{ .WireUnownedResult }}(client_end_
{{- if .RequestArgs -}}
, _request_buffer.data, _request_buffer.capacity
{{- end -}}
{{- .RequestArgs | ForwardCommaParams -}}
{{- if .HasResponse -}}
, _response_buffer.data, _response_buffer.capacity
{{- end -}});
}
{{- end }}
{{ "" }}
{{- end }}
private:
::fidl::UnownedClientEnd<{{ . }}> client_end_;
};
{{- template "ProtocolEventHandlerDeclaration" . }}
template<>
class {{ .WireSyncClient }} final {
public:
WireSyncClient() = default;
explicit WireSyncClient(::fidl::ClientEnd<{{ . }}> client_end)
: client_end_(std::move(client_end)) {}
~WireSyncClient() = default;
WireSyncClient(WireSyncClient&&) = default;
WireSyncClient& operator=(WireSyncClient&&) = default;
const ::fidl::ClientEnd<{{ . }}>& client_end() const { return client_end_; }
::fidl::ClientEnd<{{ . }}>& client_end() { return client_end_; }
const ::zx::channel& channel() const { return client_end_.channel(); }
::zx::channel* mutable_channel() { return &client_end_.channel(); }
{{ "" }}
{{- /* Client-calling functions do not apply to events. */}}
{{- range .ClientMethods -}}
{{- .Docs }}
//{{ template "ClientAllocationComment" . }}
{{ .WireResult }} {{ .Name }}({{ .RequestArgs | CalleeParams }}) {
return {{ .WireResult }}(this->client_end()
{{- .RequestArgs | ForwardCommaParams -}});
}
{{ "" }}
{{- if or .RequestArgs .ResponseArgs }}
{{- .Docs }}
// Caller provides the backing storage for FIDL message via request and response buffers.
{{ .WireUnownedResult }} {{ .Name }}({{ template "SyncRequestCallerAllocateMethodArguments" . }}) {
return {{ .WireUnownedResult }}(this->client_end()
{{- if .RequestArgs -}}
, _request_buffer.data, _request_buffer.capacity
{{- end -}}
{{- .RequestArgs | ForwardCommaParams -}}
{{- if .HasResponse -}}
, _response_buffer.data, _response_buffer.capacity
{{- end -}});
}
{{- end }}
{{ "" }}
{{- end }}
{{- if .Events }}
// Handle all possible events defined in this protocol.
// Blocks to consume exactly one message from the channel, then call the corresponding virtual
// method defined in |SyncEventHandler|. The return status of the handler function is folded with
// any transport-level errors and returned.
::fidl::Result HandleOneEvent({{ .WireSyncEventHandler }}& event_handler) {
return event_handler.HandleOneEvent(client_end_);
}
{{- end }}
private:
::fidl::ClientEnd<{{ . }}> client_end_;
};
{{- template "ProtocolInterfaceDeclaration" . }}
{{- end }}
{{- define "ProtocolTraits" -}}
{{ $protocol := . -}}
{{ range .Methods -}}
{{ $method := . -}}
{{- if .HasRequest }}
template <>
struct IsFidlType<{{ .WireRequest }}> : public std::true_type {};
template <>
struct IsFidlMessage<{{ .WireRequest }}> : public std::true_type {};
static_assert(sizeof({{ .WireRequest }})
== {{ .WireRequest }}::PrimarySize);
{{- range $index, $param := .RequestArgs }}
static_assert(offsetof({{ $method.WireRequest }}, {{ $param.Name }}) == {{ $param.Offset }});
{{- end }}
{{- end }}
{{- if .HasResponse }}
template <>
struct IsFidlType<{{ .WireResponse }}> : public std::true_type {};
template <>
struct IsFidlMessage<{{ .WireResponse }}> : public std::true_type {};
static_assert(sizeof({{ .WireResponse }})
== {{ .WireResponse }}::PrimarySize);
{{- range $index, $param := .ResponseArgs }}
static_assert(offsetof({{ $method.WireResponse }}, {{ $param.Name }}) == {{ $param.Offset }});
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- define "ProtocolDefinition" }}
{{ $protocol := . -}}
{{- range .Methods }}
{{ EnsureNamespace .OrdinalName }}
[[maybe_unused]]
constexpr uint64_t {{ .OrdinalName.Name }} = {{ .Ordinal }}lu;
{{ EnsureNamespace .Request.WireCodingTable }}
extern "C" const fidl_type_t {{ .Request.WireCodingTable.Name }};
{{ EnsureNamespace .Response.WireCodingTable }}
extern "C" const fidl_type_t {{ .Response.WireCodingTable.Name }};
{{- end }}
{{- /* Client-calling functions do not apply to events. */}}
{{- range .ClientMethods -}}
{{ "" }}
{{- template "MethodResultDefinition" . }}
{{- if or .RequestArgs .ResponseArgs }}
{{ "" }}
{{- template "MethodUnownedResultDefinition" . }}
{{- end }}
{{ "" }}
{{- end }}
{{- range .ClientMethods }}
{{ "" }}
{{- template "ClientSyncRequestManagedMethodDefinition" . }}
{{- if or .RequestArgs .ResponseArgs }}
{{ "" }}
{{- template "ClientSyncRequestCallerAllocateMethodDefinition" . }}
{{- end }}
{{- if .HasResponse }}
{{ "" }}
{{- template "MethodResponseContextDefinition" . }}
{{- template "ClientAsyncRequestManagedMethodDefinition" . }}
{{- end }}
{{- end }}
{{ template "ClientDispatchDefinition" . }}
{{ "" }}
{{- if .Events }}
{{- template "EventHandlerHandleOneEventMethodDefinition" . }}
{{- end }}
{{- /* Server implementation */}}
{{ template "ProtocolDispatcherDefinition" . }}
{{- if .Methods }}
{{ "" }}
{{- range .TwoWayMethods -}}
{{ "" }}
{{- template "ReplyManagedMethodDefinition" . }}
{{- if .Result }}
{{- template "ReplyManagedResultSuccessMethodDefinition" . }}
{{- template "ReplyManagedResultErrorMethodDefinition" . }}
{{- end }}
{{- if .ResponseArgs }}
{{ "" }}
{{- template "ReplyCallerAllocateMethodDefinition" . }}
{{- if .Result }}
{{- template "ReplyCallerAllocateResultSuccessMethodDefinition" . }}
{{- end }}
{{- end }}
{{ "" }}
{{- end }}
{{ "" }}
{{- range .Methods }}
{{- if .HasRequest }}{{ template "MethodRequestDefinition" . }}{{ end }}
{{ "" }}
{{- if .HasResponse }}{{ template "MethodResponseDefinition" . }}{{ end }}
{{ "" }}
{{- end }}
{{- end }}
{{- end }}
`