| // Copyright 2015 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. |
| |
| {% import "struct.tmpl" as struct_macros %} |
| {% import "runtime_type_macros.tmpl" as runtime_type_macros %} |
| |
| {%- macro declare_params(struct) %} |
| {%- for field in struct.fields -%} |
| {{field|name(False)}} {{field.kind|go_type}}{% if not loop.last %}, {% endif %} |
| {%- endfor %} |
| {%- endmacro %} |
| |
| |
| |
| {% macro declare_request_params(method) %} |
| ({{declare_params(method.param_struct)}}) |
| {%- if method.response_parameters|is_none_or_empty -%} |
| {{' (err error)'}} |
| {%- else -%} |
| {{' '}}({{declare_params(method.response_param_struct)}}, err error) |
| {%- endif -%} |
| {% endmacro %} |
| |
| |
| |
| {%- macro flags(method, is_response) -%} |
| {%- if not method|has_response -%} |
| bindings.MessageNoFlag |
| {%- elif is_response: -%} |
| bindings.MessageIsResponseFlag |
| {%- else -%} |
| bindings.MessageExpectsResponseFlag |
| {%- endif -%} |
| {%- endmacro -%} |
| |
| |
| |
| {% macro define(interface, descpkg, typepkg, pkg) %} |
| type {{interface|name}} interface { |
| {% for method in interface.methods %} |
| {{method|name}}{{declare_request_params(method)}} |
| {% endfor %} |
| } |
| |
| {{runtime_type_macros.maybeWriteStaticMojomTypeAccessor(typepkg, interface)}} |
| |
| {% if interface.service_name %} |
| var {{interface|name(False)}}_Name = "{{interface.service_name}}" |
| {% endif %} |
| |
| type {{interface|name}}_Request bindings.InterfaceRequest |
| |
| {% if interface.service_name %} |
| func (r *{{interface|name}}_Request) Name() string { |
| return {{interface|name(False)}}_Name |
| } |
| {% endif %} |
| |
| {%- set type_name = interface|name + '_Request' %} |
| {{runtime_type_macros.maybeWriteMojomTypeAccessor(typepkg, interface, type_name)}} |
| |
| type {{interface|name}}_Pointer bindings.InterfacePointer |
| |
| {% if interface.service_name %} |
| func (p *{{interface|name}}_Pointer) Name() string { |
| return {{interface|name(False)}}_Name |
| } |
| {% endif %} |
| |
| type {{interface|name}}_ServiceFactory struct{ |
| Delegate {{interface|name}}_Factory |
| } |
| |
| type {{interface|name}}_Factory interface { |
| Create(request {{interface|name}}_Request) |
| } |
| |
| {% if interface.service_name %} |
| func (f *{{interface|name}}_ServiceFactory) Name() string { |
| return {{interface|name(False)}}_Name |
| } |
| {% endif %} |
| |
| // TODO(rudominer) This should only be defined for top-level interfaces. |
| func (f *{{interface|name}}_ServiceFactory) ServiceDescription() {{descpkg}}ServiceDescription { |
| return &{{interface|name}}_ServiceDescription{} |
| } |
| |
| func (f *{{interface|name}}_ServiceFactory) Create(messagePipe system.MessagePipeHandle) { |
| request := {{interface|name}}_Request{bindings.NewMessagePipeHandleOwner(messagePipe)} |
| f.Delegate.Create(request) |
| } |
| |
| // CreateMessagePipeFor{{interface|name}} creates a message pipe for use with the |
| // {{interface|name}} interface with a {{interface|name}}_Request on one end and a {{interface|name}}_Pointer on the other. |
| func CreateMessagePipeFor{{interface|name}}() ({{interface|name}}_Request, {{interface|name}}_Pointer) { |
| r, p := bindings.CreateMessagePipeForMojoInterface() |
| return {{interface|name}}_Request(r), {{interface|name}}_Pointer(p) |
| } |
| |
| {% for method in interface.methods %} |
| const {{interface|name(False)}}_{{method|name}}_Name uint32 = {{method.ordinal}} |
| {% endfor %} |
| |
| type {{interface|name}}_Proxy struct { |
| router *bindings.Router |
| ids bindings.Counter |
| } |
| |
| func New{{interface|name}}Proxy(p {{interface|name}}_Pointer, waiter bindings.AsyncWaiter) *{{interface|name}}_Proxy { |
| return &{{interface|name}}_Proxy{ |
| bindings.NewRouter(p.PassMessagePipe(), waiter), |
| bindings.NewCounter(), |
| } |
| } |
| |
| func (p *{{interface|name}}_Proxy) Close_Proxy() { |
| p.router.Close() |
| } |
| |
| {% for method in interface.methods %} |
| {{struct_macros.define(method.param_struct, typepkg, pkg, False)}} |
| {%- if method|has_response %} |
| {{struct_macros.define(method.response_param_struct, typepkg, pkg, False)}} |
| {%- endif %} |
| func (p *{{interface|name}}_Proxy) {{method|name}}{{declare_request_params(method)}} { |
| payload := &{{method.param_struct|name(False)}}{ |
| {% for field in (method.param_struct).fields %} |
| {{field|name(False)}}, |
| {% endfor %} |
| } |
| header := bindings.MessageHeader{ |
| Type: {{interface|name(False)}}_{{method|name}}_Name, |
| Flags: {{flags(method, False)}}, |
| {% if method|has_response %} |
| RequestId: p.ids.Count(), |
| {% endif %} |
| } |
| var message *bindings.Message |
| if message, err = bindings.EncodeMessage(header, payload); err != nil { |
| err = fmt.Errorf("can't encode request: %v", err.Error()) |
| p.Close_Proxy() |
| return |
| } |
| {% if method|has_response %} |
| readResult := <-p.router.AcceptWithResponse(message) |
| if err = readResult.Error; err != nil { |
| p.Close_Proxy() |
| return |
| } |
| if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag { |
| err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags, |
| fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags), |
| } |
| return |
| } |
| if got, want := readResult.Message.Header.Type, {{interface|name(False)}}_{{method|name}}_Name; got != want { |
| err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod, |
| fmt.Sprintf("invalid method in response: expected %v, got %v", want, got), |
| } |
| return |
| } |
| var response {{method.response_param_struct|name(False)}} |
| if err = readResult.Message.DecodePayload(&response); err != nil { |
| p.Close_Proxy() |
| return |
| } |
| {% for field in (method.response_param_struct).fields %} |
| {{field|name(False)}} = response.{{field|name(False)}} |
| {% endfor %} |
| {% else %} |
| if err = p.router.Accept(message); err != nil { |
| p.Close_Proxy() |
| return |
| } |
| {% endif %} |
| return |
| } |
| |
| {% endfor %} |
| type {{interface|name(False)}}_Stub struct { |
| connector *bindings.Connector |
| impl {{interface|name}} |
| } |
| |
| func New{{interface|name}}Stub(r {{interface|name}}_Request, impl {{interface|name}}, waiter bindings.AsyncWaiter) *bindings.Stub { |
| connector := bindings.NewConnector(r.PassMessagePipe(), waiter) |
| return bindings.NewStub(connector, &{{interface|name(False)}}_Stub{connector, impl}) |
| } |
| |
| |
| func (f *{{interface|name}}_Request) ServiceDescription() {{descpkg}}ServiceDescription { |
| return &{{interface|name}}_ServiceDescription{} |
| } |
| |
| |
| type {{interface|name}}_ServiceDescription struct{} |
| |
| {% if should_gen_mojom_types and interface.service_name-%} |
| func (sd *{{interface|name}}_ServiceDescription) GetTopLevelInterface() (outMojomInterface {{typepkg}}MojomInterface, err error) { |
| interfaceTypeKey := getRuntimeTypeInfo().Services["{{interface.service_name}}"] |
| userDefinedType := getRuntimeTypeInfo().TypeMap[interfaceTypeKey].(*{{typepkg}}UserDefinedTypeInterfaceType) |
| return userDefinedType.Value, nil |
| } |
| |
| func (sd *{{interface|name}}_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) { |
| if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok { |
| return udt, nil |
| } |
| return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "{{interface|name}}", inTypeKey) |
| } |
| |
| func (sd *{{interface|name}}_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) { |
| o := GetAllMojomTypeDefinitions() |
| return &o, nil |
| } |
| {%- else -%} |
| func (sd *{{interface|name}}_ServiceDescription) GetTopLevelInterface() (outMojomInterface {{typepkg}}MojomInterface, err error) { |
| err = fmt.Errorf("GetTopLevelInterface not implemented") |
| return |
| } |
| |
| func (sd *{{interface|name}}_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) { |
| err = fmt.Errorf("GetTypeDefinition not implemented") |
| return |
| } |
| |
| func (sd *{{interface|name}}_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) { |
| err = fmt.Errorf("GetAllTypeDefinitions not implemented") |
| return |
| } |
| {%- endif %} |
| |
| var _ {{descpkg}}ServiceDescription = (*{{interface|name}}_ServiceDescription)(nil) |
| |
| |
| func (s *{{interface|name(False)}}_Stub) Accept(message *bindings.Message) (err error) { |
| switch message.Header.Type { |
| {% for method in interface.methods %} |
| case {{interface|name(False)}}_{{method|name}}_Name: |
| {% if method|has_response %} |
| if message.Header.Flags != bindings.MessageExpectsResponseFlag { |
| {% else %} |
| if message.Header.Flags != bindings.MessageNoFlag { |
| {% endif %} |
| return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags, |
| fmt.Sprintf("invalid message header flag: %v", message.Header.Flags), |
| } |
| } |
| var request {{method.param_struct|name(False)}} |
| if err := message.DecodePayload(&request); err != nil { |
| return err |
| } |
| {% if method|has_response %} |
| var response {{method.response_param_struct|name(False)}} |
| {% endif %} |
| {% if method.response_parameters|is_none_or_empty %} |
| err = s.impl.{{method|name}}( |
| {%- else -%} |
| {% for field in (method.response_param_struct).fields %} |
| response.{{field|name(False)}}{{', '}} |
| {%- endfor -%}err = s.impl.{{method|name}}( |
| {%- endif -%} |
| {%- for field in (method.param_struct).fields -%} |
| request.{{field|name(False)}}{% if not loop.last %}, {% endif %} |
| {%- endfor -%} |
| ) |
| if err != nil { |
| return |
| } |
| {% if method|has_response %} |
| header := bindings.MessageHeader{ |
| Type: {{interface|name(False)}}_{{method|name}}_Name, |
| Flags: {{flags(method, True)}}, |
| RequestId: message.Header.RequestId, |
| } |
| message, err = bindings.EncodeMessage(header, &response) |
| if err != nil { |
| return err |
| } |
| return s.connector.WriteMessage(message) |
| {% endif %} |
| {% endfor %} |
| default: |
| return &bindings.ValidationError{ |
| bindings.MessageHeaderUnknownMethod, |
| fmt.Sprintf("unknown method %v", message.Header.Type), |
| } |
| } |
| return |
| } |
| |
| {% endmacro %} |