// This file is generated by TypeBuilder_h.template. // Copyright (c) 2016 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h #define {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h {% if config.protocol.export_header %} #include {{format_include(config.protocol.export_header)}} {% endif %} #include {{format_include(config.protocol.package, "Protocol")}} // For each imported domain we generate a ValueConversions struct instead of a full domain definition // and include Domain::API version from there. {% for name in domain.dependencies %} {% if protocol.is_imported_dependency(name) %} #include {{format_domain_include(config.protocol.package, name)}} {% endif %} {% endfor %} {% if protocol.is_exported_domain(domain.domain) %} #include {{format_include(config.exported.package, domain.domain)}} {% endif %} {% for namespace in config.protocol.namespace %} namespace {{namespace}} { {% endfor %} namespace {{domain.domain}} { // ------------- Forward and enum declarations. {% for type in domain.types %} {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %} {% if type.type == "object" %} {% if "properties" in type %} class {{type.id}}; {% else %} using {{type.id}} = Object; {% endif %} {% elif type.type != "array" %} using {{type.id}} = {{protocol.resolve_type(type).type}}; {% endif %} {% endfor %} {% for type in domain.types %} {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %} {% if "enum" in type %} namespace {{type.id}}Enum { {% for literal in type.enum %} {{config.protocol.export_macro}} extern const char {{ literal | dash_to_camelcase}}[]; {% endfor %} } // namespace {{type.id}}Enum {% endif %} {% endfor %} {% for command in join_arrays(domain, ["commands", "events"]) %} {% for param in join_arrays(command, ["parameters", "returns"]) %} {% if "enum" in param %} namespace {{command.name | to_title_case}} { namespace {{param.name | to_title_case}}Enum { {% for literal in param.enum %} {{config.protocol.export_macro}} extern const char* {{literal | dash_to_camelcase}}; {% endfor %} } // {{param.name | to_title_case}}Enum } // {{command.name | to_title_case }} {% endif %} {% endfor %} {% endfor %} // ------------- Type and builder declarations. {% for type in domain.types %} {% if not protocol.generate_type(domain.domain, type.id) %}{% continue %}{% endif %} {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %} class {{config.protocol.export_macro}} {{type.id}} : public Serializable{% if protocol.is_exported(domain.domain, type.id) %}, public API::{{type.id}}{% endif %}{ PROTOCOL_DISALLOW_COPY({{type.id}}); public: static std::unique_ptr<{{type.id}}> fromValue(protocol::Value* value, ErrorSupport* errors); ~{{type.id}}() override { } {% for property in type.properties %} {% set property_type = protocol.resolve_type(property) %} {% set property_name = property.name | to_title_case %} {% set property_field = "m_" + property.name %} {% if "enum" in property %} struct {{config.protocol.export_macro}} {{property_name}}Enum { {% for literal in property.enum %} static const char* {{literal | dash_to_camelcase}}; {% endfor %} }; // {{property_name}}Enum {% endif %} {% if property.optional %} bool {{"has" | to_method_case}}{{property_name}}() { return {{property_field}}.isJust(); } {{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}({{property_type.raw_pass_type}} defaultValue) { return {{property_field}}.isJust() ? {{property_field}}.fromJust() : defaultValue; } {% else %} {{property_type.raw_return_type}} {{"get" | to_method_case}}{{property_name}}() { return {{property_type.to_raw_type % property_field}}; } {% endif %} void {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { {{property_field}} = {{property_type.to_rvalue % "value"}}; } {% endfor %} std::unique_ptr toValue() const; String serializeToJSON() override { return toValue()->serializeToJSON(); } std::vector serializeToBinary() override { return toValue()->serializeToBinary(); } String toJSON() const { return toValue()->toJSONString(); } std::unique_ptr<{{type.id}}> clone() const; {% if protocol.is_exported(domain.domain, type.id) %} {{config.exported.string_out}} toJSONString() const override; void writeBinary(std::vector* out) const override; {% endif %} template class {{type.id}}Builder { public: enum { NoFieldsSet = 0, {% for property in type.properties|rejectattr("optional") %} {{property.name | to_title_case}}Set = 1 << {{loop.index}}, {% endfor %} AllFieldsSet = ( {%- for property in type.properties %} {% if not(property.optional) %}{{property.name | to_title_case}}Set | {%endif %} {% endfor %}0)}; {% for property in type.properties %} {% set property_type = protocol.resolve_type(property) %} {% set property_name = property.name | to_title_case %} {% if property.optional %} {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); return *this; } {% else %} {{type.id}}Builder& {{"set" | to_method_case}}{{property_name}}({{property_type.pass_type}} value) { static_assert(!(STATE & {{property_name}}Set), "property {{property.name}} should not be set yet"); m_result->{{"set" | to_method_case}}{{property_name}}({{property_type.to_rvalue % "value"}}); return castState<{{property_name}}Set>(); } {% endif %} {% endfor %} std::unique_ptr<{{type.id}}> {{"build" | to_method_case}}() { static_assert(STATE == AllFieldsSet, "state should be AllFieldsSet"); return std::move(m_result); } private: friend class {{type.id}}; {{type.id}}Builder() : m_result(new {{type.id}}()) { } template {{type.id}}Builder& castState() { return *reinterpret_cast<{{type.id}}Builder*>(this); } {{protocol.type_definition(domain.domain + "." + type.id).type}} m_result; }; static {{type.id}}Builder<0> {{"create" | to_method_case}}() { return {{type.id}}Builder<0>(); } private: {{type.id}}() { {% for property in type.properties %} {% if not(property.optional) and "default_value" in protocol.resolve_type(property) %} m_{{property.name}} = {{protocol.resolve_type(property).default_value}}; {%endif %} {% endfor %} } {% for property in type.properties %} {% if property.optional %} Maybe<{{protocol.resolve_type(property).raw_type}}> m_{{property.name}}; {% else %} {{protocol.resolve_type(property).type}} m_{{property.name}}; {% endif %} {% endfor %} }; {% endfor %} // ------------- Backend interface. class {{config.protocol.export_macro}} Backend { public: virtual ~Backend() { } {% for command in domain.commands %} {% if "redirect" in command %}{% continue %}{% endif %} {% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %} {% if protocol.is_async_command(domain.domain, command.name) %} class {{config.protocol.export_macro}} {{command.name | to_title_case}}Callback { public: virtual void sendSuccess( {%- for parameter in command.returns -%} {%- if "optional" in parameter -%} Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}} {%- else -%} {{protocol.resolve_type(parameter).pass_type}} {{parameter.name}} {%- endif -%} {%- if not loop.last -%}, {% endif -%} {%- endfor -%} ) = 0; virtual void sendFailure(const DispatchResponse&) = 0; virtual void fallThrough() = 0; virtual ~{{command.name | to_title_case}}Callback() { } }; {% endif %} {%- if not protocol.is_async_command(domain.domain, command.name) %} virtual DispatchResponse {{command.name | to_method_case}}( {%- else %} virtual void {{command.name | to_method_case}}( {%- endif %} {%- for parameter in command.parameters -%} {%- if not loop.first -%}, {% endif -%} {%- if "optional" in parameter -%} Maybe<{{protocol.resolve_type(parameter).raw_type}}> in_{{parameter.name}} {%- else -%} {{protocol.resolve_type(parameter).pass_type}} in_{{parameter.name}} {%- endif -%} {%- endfor -%} {%- if protocol.is_async_command(domain.domain, command.name) -%} {%- if command.parameters -%}, {% endif -%} std::unique_ptr<{{command.name | to_title_case}}Callback> callback {%- else -%} {%- for parameter in command.returns -%} {%- if (not loop.first) or command.parameters -%}, {% endif -%} {%- if "optional" in parameter -%} Maybe<{{protocol.resolve_type(parameter).raw_type}}>* out_{{parameter.name}} {%- else -%} {{protocol.resolve_type(parameter).type}}* out_{{parameter.name}} {%- endif -%} {%- endfor -%} {%- endif -%} ) = 0; {% endfor %} {% if protocol.generate_disable(domain) %} virtual DispatchResponse {{"disable" | to_method_case}}() { return DispatchResponse::OK(); } {% endif %} }; // ------------- Frontend interface. class {{config.protocol.export_macro}} Frontend { public: explicit Frontend(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { } {% for event in domain.events %} {% if not protocol.generate_event(domain.domain, event.name) %}{% continue %}{% endif %} void {{event.name | to_method_case}}( {%- for parameter in event.parameters -%} {%- if "optional" in parameter -%} Maybe<{{protocol.resolve_type(parameter).raw_type}}> {{parameter.name}} = Maybe<{{protocol.resolve_type(parameter).raw_type}}>() {%- else -%} {{protocol.resolve_type(parameter).pass_type}} {{parameter.name}} {%- endif -%}{%- if not loop.last -%}, {% endif -%} {%- endfor -%} ); {% endfor %} void flush(); void sendRawJSONNotification(String); void sendRawCBORNotification(std::vector); private: FrontendChannel* m_frontendChannel; }; // ------------- Dispatcher. class {{config.protocol.export_macro}} Dispatcher { public: static void wire(UberDispatcher*, Backend*); private: Dispatcher() { } }; // ------------- Metainfo. class {{config.protocol.export_macro}} Metainfo { public: using BackendClass = Backend; using FrontendClass = Frontend; using DispatcherClass = Dispatcher; static const char domainName[]; static const char commandPrefix[]; static const char version[]; }; } // namespace {{domain.domain}} {% for namespace in config.protocol.namespace %} } // namespace {{namespace}} {% endfor %} #endif // !defined({{"_".join(config.protocol.namespace)}}_{{domain.domain}}_h)