blob: 0b1564a0ad2c500b6ca0e7e690aa298cac35de73 [file] [log] [blame]
{{/*
This is an example fidlmerge template. It generates .h and .cc files for the
ostream operator<< overloads required to print the types generated by fidlmerge
for FIDL enums, structs and unions.
NOTE: This template uses some indenting capabilities that aren't currently
implemented in the tree.
NOTE: This template generates a "#pragma once", which should be replaced by
an #ifndef guard to conform to the style guide. scripts/git-file-format will do
this automatically.
*/}}
{{/* Produces the copyright messages for a file header. */}}
{{/* TODO: variable copyright year. */}}
{{- define "FileHeader" -}}
// 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.
//
// WARNING: This file is machine generated by fidlmerge.
{{- end }}
{{- define "ThisFidlInclude" -}}
#include <{{- range .Name.Parts}}{{ . }}/{{ end }}cpp/fidl.h>
{{ end }}
{{- define "IncludeHeader" }}
{{- template "FileHeader" }}
#pragma once
{{ template "ThisFidlInclude" . }}
{{- range .Name.Parts }}
namespace {{ . }} {
{{- end }}
// Because the FIDL compiler back end generates simple ostream formatters for
// enums, WrapEnum is used to allow for alternative formatters.
// e.g. os << WrapEnum(enum_value);
template <typename T>
struct WrapEnum {
WrapEnum(T actual) : actual_(actual) {}
T actual_;
};
{{ end }}
{{- define "NamespaceClose" }}
{{/* keep the newline */}}
{{- range .Name.PartsReversed }}
} // namespace {{ . }}
{{- end }}
{{- end }}
{{/* Produces a C++ expression for a types.EncodedCompoundIdentifier. */}}
{{/* The expression is qualified for use in the subject namespace. */}}
{{- define "Id" }}
{{- if isLocal . }}
{{- .Parts.Name }}
{{- else }}
{{- template "QualifiedId" . }}
{{- end }}
{{- end }}
{{- define "EnumWriterDecls" }}
{{- range .Enums }}
std::ostream& operator<<(std::ostream& os, const WrapEnum<{{ .Name.Parts.Name }}>& value);
{{- end }}
{{- end }}
{{- define "StructWriterDecls" }}
{{- range .Structs }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
{{- end }}
{{- end }}
{{- define "UnionWriterDecls" }}
{{- range .Unions }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
{{- end }}
{{- end }}
{{- define "ImplementationHeader" }}
{{- template "FileHeader" }}
// TODO: Fix this include to reference the generated include file.
#include "..."
#include "lib/fostr/fidl_types.h"
{{/* keep the newline */}}
{{- range .Name.Parts }}
namespace {{ . }} {
{{- end }}
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& value) {
if (!value) {
return os << "<null>";
}
return os << *value;
}
{{/* keep the newline */}}
{{- end }}
{{- define "EnumWriterDefs" }}
{{- range .Enums }}
{{- $type_name := .Name.Parts.Name }}
std::ostream& operator<<(std::ostream& os, const WrapEnum<{{ .Name.Parts.Name }}>& value) {
switch (value.actual_) {
{{- range .Members }}
case {{ $type_name }}::{{ .Name }}:
return os << "{{ toFriendlyCase .Name }}";
{{- end }}
}
return os;
}
{{/* keep the newline */}}
{{- end }}
{{- end }}
{{- define "StructWriterDefs" }}
{{- range .Structs }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
os << fostr::Indent;
{{- range .Members }}
{{- if eq .Type.Kind "identifier" }}
{{- if eq (declType .Type.Identifier) "enum" }}
os << fostr::NewLine << "{{ .Name }}: " << WrapEnum<{{ template "Id" .Type.Identifier }}>(value.{{ .Name }});
{{- else }}
os << fostr::NewLine << "{{ .Name }}: " << value.{{ .Name }};
{{- end }}
{{- else }}
os << fostr::NewLine << "{{ .Name }}: " << value.{{ .Name }};
{{- end }}
{{- end }}
return os << fostr::Outdent;
}
{{- end }}
{{- end }}
{{- define "UnionWriterDefs" }}
{{- range .Unions }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
switch (value.Which()) {
{{- $type_name := .Name.Parts.Name }}
{{- range .Members }}
case {{ $type_name }}::Tag::k{{ toUpperCamelCase .Name }}:
{{- if eq .Type.Kind "identifier" }}
{{- if eq (declType .Type.Identifier) "enum" }}
return os << "{{ toSnakeCase .Name }} " << WrapEnum<{{ template "Id" .Type.Identifier }}>(value.{{ toSnakeCase .Name }}());
{{- else }}
return os << "{{ toSnakeCase .Name }} " << value.{{ toSnakeCase .Name }}();
{{- end }}
{{- else }}
return os << "{{ toSnakeCase .Name }} " << value.{{ toSnakeCase .Name }}();
{{- end }}
{{- end }}
case {{ $type_name }}::Tag::Invalid:
return os << "<invalid union>";
}
return os;
}
{{- end }}
{{- end }}
{{- define "IncludeFile" }}
{{- template "IncludeHeader" . }}
{{- template "EnumWriterDecls" . }}
{{- template "StructWriterDecls" . }}
{{- template "UnionWriterDecls" . }}
{{- template "NamespaceClose" . }}
{{- end }}
{{- define "ImplementationFile" }}
{{- template "ImplementationHeader" . }}
{{- template "EnumWriterDefs" . }}
{{- template "StructWriterDefs" . }}
{{- template "UnionWriterDefs" . }}
{{- template "NamespaceClose" . }}
{{- end }}
{{- define "Main" }}
{{- $include_path := .Output ".h" }}
{{- $implementation_path := .Output ".cc" }}
{{ .Generate $include_path "IncludeFile" . }}
{{ .Generate $implementation_path "ImplementationFile" . }}
{{end}}