15267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#!/usr/bin/env python
25267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# Copyright (c) 2013 Google Inc. All rights reserved.
35267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#
45267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# Redistribution and use in source and binary forms, with or without
55267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# modification, are permitted provided that the following conditions are
65267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# met:
75267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#
85267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#     * Redistributions of source code must retain the above copyright
95267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# notice, this list of conditions and the following disclaimer.
105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#     * Redistributions in binary form must reproduce the above
115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer
125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# in the documentation and/or other materials provided with the
135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# distribution.
145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#     * Neither the name of Google Inc. nor the names of its
155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# contributors may be used to endorse or promote products derived from
165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# this software without specific prior written permission.
175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#
185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)import optparse
315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)import re
325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)import string
335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)import sys
345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_h = string.Template("""// Code generated from InspectorInstrumentation.idl
365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
37521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifndef ${file_name}_h
38521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#define ${file_name}_h
39521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
40521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${includes}
415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace WebCore {
435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace InspectorInstrumentation {
455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)$methods
475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} // namespace InspectorInstrumentation
485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} // namespace WebCore
505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
51521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif // !defined(${file_name}_h)
525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)""")
535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_inline = string.Template("""
555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)inline void ${name}(${params_public})
565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){   ${fast_return}
57521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (${condition})
585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        ${name}Impl(${params_impl});
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)""")
615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_inline_forward = string.Template("""
635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)inline void ${name}(${params_public})
645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){   ${fast_return}
655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ${name}Impl(${params_impl});
665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)""")
685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
69521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)template_inline_returns_value = string.Template("""
70521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)inline ${return_type} ${name}(${params_public})
715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){   ${fast_return}
72521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    if (${condition})
735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return ${name}Impl(${params_impl});
74521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return ${default_return_value};
755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)""")
775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_cpp = string.Template("""// Code generated from InspectorInstrumentation.idl
805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "config.h"
82521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
83521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${includes}
845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace WebCore {
86521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${extra_definitions}
875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace InspectorInstrumentation {
895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)$methods
905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} // namespace InspectorInstrumentation
925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} // namespace WebCore
945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)""")
955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_outofline = string.Template("""
97521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${return_type} ${name}Impl(${params_impl})
98521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){${impl_lines}
995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}""")
1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_agent_call = string.Template("""
1025267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (${agent_class}* agent = ${agent_fetch})
103521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        ${maybe_return}agent->${name}(${params_agent});""")
1045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template_agent_call_timeline_returns_cookie = string.Template("""
1065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    int timelineAgentId = 0;
1075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (InspectorTimelineAgent* agent = agents->inspectorTimelineAgent()) {
1085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (agent->${name}(${params_agent}))
1095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            timelineAgentId = agent->id();
1105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }""")
1115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
112521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
113521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)template_instrumenting_agents_h = string.Template("""// Code generated from InspectorInstrumentation.idl
114521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
115521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#ifndef InstrumentingAgentsInl_h
116521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#define InstrumentingAgentsInl_h
117521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
118e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/FastAllocBase.h"
119e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/Noncopyable.h"
120e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/PassRefPtr.h"
121e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/RefCounted.h"
122521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
123521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)namespace WebCore {
124521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
125521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${forward_list}
126521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
127521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)class InstrumentingAgents : public RefCounted<InstrumentingAgents> {
128521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    WTF_MAKE_NONCOPYABLE(InstrumentingAgents);
129521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    WTF_MAKE_FAST_ALLOCATED;
130521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)public:
131521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    static PassRefPtr<InstrumentingAgents> create()
132521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    {
133521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return adoptRef(new InstrumentingAgents());
134521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    }
135521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ~InstrumentingAgents() { }
136521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    void reset();
137521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
138521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${accessor_list}
139521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
140521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)private:
141521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    InstrumentingAgents();
142521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
143521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)${member_list}
144521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)};
145521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
146521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
147521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
148521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#endif // !defined(InstrumentingAgentsInl_h)
149521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)""")
150521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
151521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)template_instrumenting_agent_accessor = string.Template("""
152521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    ${class_name}* ${getter_name}() const { return ${member_name}; }
153521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    void set${class_name}(${class_name}* agent) { ${member_name} = agent; }""")
154521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
155521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)template_instrumenting_agents_cpp = string.Template("""
156521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)InstrumentingAgents::InstrumentingAgents()
157521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    : $init_list
158521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
159521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
160521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
161521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void InstrumentingAgents::reset()
162521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
163521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    $reset_list
1645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}""")
1655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
167521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)def match_and_consume(pattern, source):
1695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    match = re.match(pattern, source)
1705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if match:
1715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return match, source[len(match.group(0)):].strip()
1725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return None, source
1735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)def load_model_from_idl(source):
176521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    source = re.sub("//.*", "", source)  # Remove line comments
177521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    source = re.sub("/\*(.|\n)*?\*/", "", source, re.MULTILINE)  # Remove block comments
178521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    source = re.sub("\]\s*?\n\s*", "] ", source)  # Merge the method annotation with the next line
1795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    source = source.strip()
1805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
181521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    model = []
182521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
183521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    while len(source):
184521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        match, source = match_and_consume("interface\s(\w*)\s?\{([^\{]*)\}", source)
185521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if not match:
186521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            sys.stderr.write("Cannot parse %s\n" % source[:100])
187521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            sys.exit(1)
188521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        model.append(File(match.group(1), match.group(2)))
189521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
190521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return model
191521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
192521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
193521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)class File:
194521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    def __init__(self, name, source):
195521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.name = name
196521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.header_name = self.name + "Inl"
197521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.includes = [include_inspector_header("InspectorInstrumentation")]
198521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.declarations = []
199521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        for line in map(str.strip, source.split("\n")):
200521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            line = re.sub("\s{2,}", " ", line).strip()  # Collapse whitespace
201521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if len(line) == 0:
202521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                continue
203521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if line[0] == "#":
204521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                self.includes.append(line)
205521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            else:
206521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                self.declarations.append(Method(line))
207521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.includes.sort()
2085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
209521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    def generate(self, cpp_lines, used_agents):
210521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        header_lines = []
211521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        for declaration in self.declarations:
212521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            for agent in set(declaration.agents):
213521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                used_agents.add(agent)
214521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            declaration.generate_header(header_lines)
215521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            declaration.generate_cpp(cpp_lines)
216521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
217521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return template_h.substitute(None,
218521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                     file_name=self.header_name,
219521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                     includes="\n".join(self.includes),
220521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                     methods="\n".join(header_lines))
2215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class Method:
2245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def __init__(self, source):
225521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        match = re.match("(\[[\w|,|=|\s]*\])?\s?(\w*\*?) (\w*)\((.*)\)\s?;", source)
2265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if not match:
2275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            sys.stderr.write("Cannot parse %s\n" % source)
2285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            sys.exit(1)
2295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        self.options = []
2315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if match.group(1):
2325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            options_str = re.sub("\s", "", match.group(1)[1:-1])
2335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            if len(options_str) != 0:
2345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                self.options = options_str.split(",")
2355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        self.return_type = match.group(2)
2375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        self.name = match.group(3)
2395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
2405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        # Splitting parameters by a comma, assuming that attribute lists contain no more than one attribute.
2415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        self.params = map(Parameter, map(str.strip, match.group(4).split(",")))
2425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.accepts_cookie = len(self.params) and self.params[0].type == "const InspectorInstrumentationCookie&"
244521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.returns_cookie = self.return_type == "InspectorInstrumentationCookie"
245521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
246521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.returns_value = self.return_type != "void"
247521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
248521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if self.return_type == "bool":
249521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            self.default_return_value = "false"
250521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        elif self.return_type == "String":
251521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            self.default_return_value = "\"\""
252521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
253521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            self.default_return_value = self.return_type + "()"
254521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
255521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        for param in self.params:
256521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if "DefaultReturn" in param.options:
257521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                self.default_return_value = param.name
258521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
259521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.params_impl = self.params
260521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if not self.accepts_cookie and not "Inline=Forward" in self.options:
261521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if not "Keep" in self.params_impl[0].options:
262521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                self.params_impl = self.params_impl[1:]
263521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            self.params_impl = [Parameter("InstrumentingAgents* agents")] + self.params_impl
264521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
265521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        self.agents = filter(lambda option: not "=" in option, self.options)
266521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
267521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    def generate_header(self, header_lines):
268521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if "Inline=Custom" in self.options:
269521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            return
270521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
271521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        header_lines.append("%s %sImpl(%s);" % (
272521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            self.return_type, self.name, ", ".join(map(Parameter.to_str_class, self.params_impl))))
273521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
274521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if "Inline=FastReturn" in self.options or "Inline=Forward" in self.options:
275521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            fast_return = "\n    FAST_RETURN_IF_NO_FRONTENDS(%s);" % self.default_return_value
276521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
277521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            fast_return = ""
278521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
279591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        for param in self.params:
280591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            if "FastReturn" in param.options:
281591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch                fast_return += "\n    if (!%s)\n        return %s;" % (param.name, self.default_return_value)
282591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch
283521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if self.accepts_cookie:
284521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            condition = "%s.isValid()" % self.params_impl[0].name
285521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            template = template_inline
286521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        elif "Inline=Forward" in self.options:
287521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            condition = ""
288521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            template = template_inline_forward
289521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
2908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            condition = "InstrumentingAgents* agents = instrumentingAgentsFor(%s)" % self.params[0].name
291521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
292521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if self.returns_value:
293521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                template = template_inline_returns_value
294521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            else:
295521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                template = template_inline
296521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
297521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        header_lines.append(template.substitute(
298521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            None,
299521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            name=self.name,
300521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            fast_return=fast_return,
301521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            return_type=self.return_type,
302521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            default_return_value=self.default_return_value,
303521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            params_public=", ".join(map(Parameter.to_str_full, self.params)),
304521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            params_impl=", ".join(map(Parameter.to_str_name, self.params_impl)),
305521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            condition=condition))
306521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
307521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    def generate_cpp(self, cpp_lines):
308521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if len(self.agents) == 0:
309521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            return
310521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
311521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        body_lines = map(self.generate_agent_call, self.agents)
312521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
313521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if self.returns_cookie:
314521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            if "Timeline" in self.agents:
315521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                timeline_agent_id = "timelineAgentId"
316521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            else:
317521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                timeline_agent_id = "0"
318521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            body_lines.append("\n    return InspectorInstrumentationCookie(agents, %s);" % timeline_agent_id)
319521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        elif self.returns_value:
320521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            body_lines.append("\n    return %s;" % self.default_return_value)
321521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
322521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        cpp_lines.append(template_outofline.substitute(
323521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            None,
324521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            return_type=self.return_type,
325521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            name=self.name,
326521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            params_impl=", ".join(map(Parameter.to_str_class_and_name, self.params_impl)),
327521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            impl_lines="".join(body_lines)))
328521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
329521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    def generate_agent_call(self, agent):
330521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        agent_class, agent_getter = agent_getter_signature(agent)
331521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
332521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        leading_param_name = self.params_impl[0].name
333521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if not self.accepts_cookie:
334521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            agent_fetch = "%s->%s()" % (leading_param_name, agent_getter)
335521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        elif agent == "Timeline":
336521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            agent_fetch = "retrieveTimelineAgent(%s)" % leading_param_name
337521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
338521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            agent_fetch = "%s.instrumentingAgents()->%s()" % (leading_param_name, agent_getter)
339521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
340521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if agent == "Timeline" and self.returns_cookie:
341521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            template = template_agent_call_timeline_returns_cookie
342521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
343521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            template = template_agent_call
344521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
345521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        if not self.returns_value or self.returns_cookie:
346521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            maybe_return = ""
347521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        else:
348521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            maybe_return = "return "
349521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
350521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        return template.substitute(
351521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            None,
352521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            name=self.name,
353521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            agent_class=agent_class,
354521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            agent_fetch=agent_fetch,
355521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            maybe_return=maybe_return,
35607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            params_agent=", ".join(map(Parameter.to_str_value, self.params_impl)[1:]))
357521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
3585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class Parameter:
3605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def __init__(self, source):
3615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        self.options = []
3625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        match, source = match_and_consume("\[(\w*)\]", source)
3635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if match:
3645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.options.append(match.group(1))
3655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        parts = map(str.strip, source.split("="))
3675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if len(parts) == 1:
3685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.default_value = None
3695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        else:
3705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.default_value = parts[1]
3715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        param_decl = parts[0]
3735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if re.match("(const|unsigned long) ", param_decl):
3755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            min_type_tokens = 2
3765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        else:
3775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            min_type_tokens = 1
3785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if len(param_decl.split(" ")) > min_type_tokens:
3805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            parts = param_decl.split(" ")
3815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.type = " ".join(parts[:-1])
3825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.name = parts[-1]
3835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        else:
3845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.type = param_decl
3855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            self.name = generate_param_name(self.type)
3865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
38707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if re.match("PassRefPtr<", param_decl):
38807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            self.value = "%s.get()" % self.name
38907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        else:
39007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            self.value = self.name
39107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
39207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
3935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def to_str_full(self):
3945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if self.default_value is None:
3955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return self.to_str_class_and_name()
3965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return "%s %s = %s" % (self.type, self.name, self.default_value)
3975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
3985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def to_str_class_and_name(self):
3995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return "%s %s" % (self.type, self.name)
4005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def to_str_class(self):
4025267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return self.type
4035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    def to_str_name(self):
4055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return self.name
4065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
40707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    def to_str_value(self):
40807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return self.value
40907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
4105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)def generate_param_name(param_type):
4125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base_name = re.match("(const |PassRefPtr<)?(\w*)", param_type).group(2)
4135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return "param" + base_name
4145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)def agent_class_name(agent):
41709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    custom_agent_names = ["PageDebugger", "PageRuntime", "WorkerRuntime"]
4185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if agent in custom_agent_names:
4195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return "%sAgent" % agent
4205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    return "Inspector%sAgent" % agent
4215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
423521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)def agent_getter_signature(agent):
424521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    agent_class = agent_class_name(agent)
425521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return agent_class, agent_class[0].lower() + agent_class[1:]
4265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
428521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)def include_header(name):
429521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return "#include \"%s.h\"" % name
4305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
432521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)def include_inspector_header(name):
433521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return include_header("core/inspector/" + name)
4345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
436521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)def generate_instrumenting_agents(used_agents):
437521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    agents = list(used_agents)
4385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
439521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    forward_list = []
440521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    accessor_list = []
441521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    member_list = []
442521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    init_list = []
443521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    reset_list = []
444521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
445521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    for agent in agents:
446521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        class_name, getter_name = agent_getter_signature(agent)
447521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        member_name = "m_" + getter_name
4485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
449521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        forward_list.append("class %s;" % class_name)
450521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        accessor_list.append(template_instrumenting_agent_accessor.substitute(
451521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            None,
452521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            class_name=class_name,
453521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            getter_name=getter_name,
454521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)            member_name=member_name))
455521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        member_list.append("    %s* %s;" % (class_name, member_name))
456521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        init_list.append("%s(0)" % member_name)
457521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        reset_list.append("%s = 0;" % member_name)
4585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
459521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    forward_list.sort()
460521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    accessor_list.sort()
461521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    member_list.sort()
462521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    init_list.sort()
463521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    reset_list.sort()
464521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
465521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    header_lines = template_instrumenting_agents_h.substitute(
466521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        None,
467521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        forward_list="\n".join(forward_list),
468521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        accessor_list="\n".join(accessor_list),
469521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        member_list="\n".join(member_list))
4705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
471521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    cpp_lines = template_instrumenting_agents_cpp.substitute(
472521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        None,
473521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        init_list="\n    , ".join(init_list),
474521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        reset_list="\n    ".join(reset_list))
4755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
476521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    return header_lines, cpp_lines
4775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
4785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
479e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochdef generate(input_path, output_dir):
480521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    fin = open(input_path, "r")
481521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    files = load_model_from_idl(fin.read())
482521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    fin.close()
4835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
484521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    cpp_includes = []
485521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    cpp_lines = []
486521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    used_agents = set()
487521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    for f in files:
488521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        cpp_includes.append(include_header(f.header_name))
4895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
490e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        fout = open(output_dir + "/" + f.header_name + ".h", "w")
491521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        fout.write(f.generate(cpp_lines, used_agents))
492521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        fout.close()
4935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
494521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    for agent in used_agents:
495521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        cpp_includes.append(include_inspector_header(agent_class_name(agent)))
496521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    cpp_includes.append(include_header("InstrumentingAgentsInl"))
497521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    cpp_includes.sort()
4985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
499521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    instrumenting_agents_header, instrumenting_agents_cpp = generate_instrumenting_agents(used_agents)
5005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
501e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    fout = open(output_dir + "/" + "InstrumentingAgentsInl.h", "w")
502521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    fout.write(instrumenting_agents_header)
5035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    fout.close()
5045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
505e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    fout = open(output_dir + "/InspectorInstrumentationImpl.cpp", "w")
506521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    fout.write(template_cpp.substitute(None,
507521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                       includes="\n".join(cpp_includes),
508521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                       extra_definitions=instrumenting_agents_cpp,
509521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                                       methods="\n".join(cpp_lines)))
5105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    fout.close()
5115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
5125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
5135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)cmdline_parser = optparse.OptionParser()
514e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochcmdline_parser.add_option("--output_dir")
5155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
5165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)try:
5175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    arg_options, arg_values = cmdline_parser.parse_args()
5185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    if (len(arg_values) != 1):
5195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
5205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    input_path = arg_values[0]
521e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    output_dirpath = arg_options.output_dir
522e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if not output_dirpath:
523e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        raise Exception("Output directory must be specified")
5245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)except Exception:
5255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
5265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    exc = sys.exc_info()[1]
5275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
528e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    sys.stderr.write("Usage: <script> --output_dir <output_dir> InspectorInstrumentation.idl\n")
5295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    exit(1)
5305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
531e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochgenerate(input_path, output_dirpath)
532