summaryrefslogtreecommitdiffstats
path: root/vpp-api/java/jvpp/gen/jvpp_gen.py
blob: 1b9ceff8078353c4c83000b221d9974fa0776468 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
#
# Copyright (c) 2016 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
# l
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import argparse
import importlib
import sys
import os

from jvppgen import types_gen
from jvppgen import callback_gen
from jvppgen import notification_gen
from jvppgen import dto_gen
from jvppgen import jvpp_callback_facade_gen
from jvppgen import jvpp_future_facade_gen
from jvppgen import jvpp_impl_gen
from jvppgen import jvpp_c_gen
from jvppgen import util

# Invocation:
# ~/Projects/vpp/vpp-api/jvpp/gen$ mkdir -p java/io/fd/vpp/jvpp && cd java/io/fd/vpp/jvpp
# ~/Projects/vpp/vpp-api/jvpp/gen/java/io/fd/vpp/jvpp$ ../../../../jvpp_gen.py -idefs_api_vpp_papi.py
#
# Compilation:
# ~/Projects/vpp/vpp-api/jvpp/gen/java/io/fd/vpp/jvpp$ javac *.java dto/*.java callback/*.java
#
# where
# defs_api_vpp_papi.py - vpe.api in python format (generated by vppapigen)

parser = argparse.ArgumentParser(description='VPP Java API generator')
parser.add_argument('-i', action="store", dest="inputfile")
parser.add_argument('--plugin_name', action="store", dest="plugin_name")
args = parser.parse_args()

sys.path.append(".")

print "Generating Java API for %s" % args.inputfile
importdir = os.path.dirname(args.inputfile)
print "importdir %s" % importdir
inputfile = os.path.basename(args.inputfile)
inputfile = inputfile.replace('.py', '')
print "inputfile %s" % inputfile
plugin_name = args.plugin_name
print "plugin_name %s" % plugin_name
sys.path.append(importdir)
cfg = importlib.import_module(inputfile, package=None)

def is_request_field(field_name):
    return field_name not in {'_vl_msg_id', 'client_index', 'context'}


def is_response_field(field_name):
    return field_name not in {'_vl_msg_id'}


def get_args(t, filter):
    arg_list = []
    for i in t:
        if not filter(i[1]):
            continue
        arg_list.append(i[1])
    return arg_list


def get_types(t, filter):
    types_list = []
    lengths_list = []
    for i in t:
        if not filter(i[1]):
            continue
        if len(i) is 3:  # array type
            types_list.append(i[0] + '[]')
            lengths_list.append((i[2], False))
        elif len(i) is 4:  # variable length array type
            types_list.append(i[0] + '[]')
            lengths_list.append((i[3], True))
        else:  # primitive type
            types_list.append(i[0])
            lengths_list.append((0, False))
    return types_list, lengths_list


def get_definitions(defs):
    # Pass 1
    func_list = []
    func_name = {}
    for a in defs:
        java_name = util.underscore_to_camelcase(a[0])

        # For replies include all the arguments except message_id
        if util.is_reply(java_name):
            types, lengths = get_types(a[1:], is_response_field)
            func_name[a[0]] = dict(
                [('name', a[0]), ('java_name', java_name),
                 ('args', get_args(a[1:], is_response_field)), ('full_args', get_args(a[1:], lambda x: True)),
                 ('types', types), ('lengths', lengths)])
        # For requests skip message_id, client_id and context
        else:
            types, lengths = get_types(a[1:], is_request_field)
            func_name[a[0]] = dict(
                [('name', a[0]), ('java_name', java_name),
                 ('args', get_args(a[1:], is_request_field)), ('full_args', get_args(a[1:], lambda x: True)),
                 ('types', types), ('lengths', lengths)])

        # Indexed by name
        func_list.append(func_name[a[0]])
    return func_list, func_name


base_package = 'io.fd.vpp.jvpp'
plugin_package = base_package + '.' + plugin_name
types_package = 'types'
dto_package = 'dto'
callback_package = 'callback'
notification_package = 'notification'
future_package = 'future'
# TODO find better package name
callback_facade_package = 'callfacade'

types_list, types_name = get_definitions(cfg.types)

types_gen.generate_types(types_list, plugin_package, types_package, inputfile)

func_list, func_name = get_definitions(cfg.messages)
dto_gen.generate_dtos(func_list, base_package, plugin_package, plugin_name.title(), dto_package, args.inputfile)
jvpp_impl_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name, dto_package, args.inputfile)
callback_gen.generate_callbacks(func_list, base_package, plugin_package, plugin_name.title(), callback_package, dto_package, args.inputfile)
notification_gen.generate_notification_registry(func_list, base_package, plugin_package, plugin_name.title(), notification_package, callback_package, dto_package, args.inputfile)
jvpp_c_gen.generate_jvpp(func_list, plugin_name, args.inputfile)
jvpp_future_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, future_package, args.inputfile)
jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, plugin_package, plugin_name.title(), dto_package, callback_package, notification_package, callback_facade_package, args.inputfile)

print "Java API for %s generated successfully" % args.inputfile
_msg_q_attach (fifo_segment_t *fs, uword offset, u32 mq_index); /** * Discover mqs on mq only segment * * @param fs fifo segment for mq * @param fds array of fds is mqs use eventfds * @param n_fds number of fds */ void fifo_segment_msg_qs_discover (fifo_segment_t *fs, int *fds, u32 n_fds); /** * Message queue offset on segment * * @param fs fifo segment for mq * @param mq_index index of mq in private mqs vector * @return offset of the shared mq the private mq is attached to */ uword fifo_segment_msg_q_offset (fifo_segment_t *fs, u32 mq_index); /** * Try to preallocate fifo headers * * Tries to preallocate fifo headers and adds them to freelist. * * @param fs fifo segment * @param batch_size number of chunks to be allocated * @return 0 on success, negative number otherwise */ int fifo_segment_prealloc_fifo_hdrs (fifo_segment_t * fs, u32 slice_index, u32 batch_size); /** * Try to preallocate fifo chunks on segment * * Tries to preallocate chunks of requested size on segment and adds them * to chunk freelist. * * @param fs fifo segment * @param chunk_size size of chunks to be allocated in bytes * @param batch_size number of chunks to be allocated * @return 0 on success, negative number otherwise */ int fifo_segment_prealloc_fifo_chunks (fifo_segment_t * fs, u32 slice_index, u32 chunk_size, u32 batch_size); /** * Pre-allocates fifo pairs in fifo segment * * The number of fifos pre-allocated is the minimum of the requested number * of pairs and the maximum number that fit within the segment. If the maximum * is hit, the number of fifo pairs requested is updated by subtracting the * number of fifos that have been successfully allocated. * * @param fs fifo segment for fifo * @param rx_fifo_size data size of rx fifos * @param tx_fifo_size data size of tx fifos * @param n_fifo_pairs number of pairs requested. Prior to returning, this * is decremented by the the number of pairs allocated. */ void fifo_segment_preallocate_fifo_pairs (fifo_segment_t * fs, u32 rx_fifo_size, u32 tx_fifo_size, u32 * n_fifo_pairs); /** * Allocate chunks in fifo segment * * @param fsh fifo segment header * @param slice_index slice where chunks should be alocated * @param chunk_size chunk size needed * @return chunk (or chunks) that cover at least chunk_size bytes * on success, 0 on failure. */ svm_fifo_chunk_t *fsh_alloc_chunk (fifo_segment_header_t * fsh, u32 slice_index, u32 chunk_size); /** * Return chunks to fifo segment * * @param fsh fifo segment header * @param slice_index slice where chunks should be returned * @param c pointer to first chunk in 0 terminated linked list */ void fsh_collect_chunks (fifo_segment_header_t * fsh, u32 slice_index, svm_fifo_chunk_t * c); /** * Fifo segment reset mem limit flag * * @param fs fifo segment * @param size size requested * @return pointer to memory allocated or 0 */ void *fifo_segment_alloc (fifo_segment_t *fs, uword size); /** * Fifo segment allocated size * * Returns fifo segment's allocated size * * @param fs fifo segment * @return allocated size in bytes */ uword fifo_segment_size (fifo_segment_t * fs); /** * Fifo segment estimate of number of free bytes * * Returns fifo segment's internal estimate of the number of free bytes. * To force a synchronization between the segment and the underlying * memory allocator, call @ref fifo_segment_update_free_bytes * * @param fs fifo segment * @return free bytes estimate */ uword fifo_segment_free_bytes (fifo_segment_t * fs); /** * Fifo segment number of cached bytes * * Returns fifo segment's number of cached bytes. * * @param fs fifo segment * @return cached bytes */ uword fifo_segment_cached_bytes (fifo_segment_t * fs); uword fifo_segment_available_bytes (fifo_segment_t * fs); /** * Number of bytes on chunk free lists * * @param fs fifo segment * @return free bytes on chunk free lists */ uword fifo_segment_fl_chunk_bytes (fifo_segment_t * fs); u8 fifo_segment_has_fifos (fifo_segment_t * fs); svm_fifo_t *fifo_segment_get_slice_fifo_list (fifo_segment_t * fs, u32 slice_index); u32 fifo_segment_num_fifos (fifo_segment_t * fs); u32 fifo_segment_num_free_fifos (fifo_segment_t * fs); svm_fifo_chunk_t *fifo_segment_alloc_chunk_w_slice (fifo_segment_t *fs, u32 slice_index, u32 chunk_size); void fifo_segment_collect_chunk (fifo_segment_t *fs, u32 slice_index, svm_fifo_chunk_t *c); uword fifo_segment_chunk_offset (fifo_segment_t *fs, svm_fifo_chunk_t *c); /** * Find number of free chunks of given size * * @param fs fifo segment * @param size chunk size of interest or ~0 if all should be counted * @return number of chunks of given size */ u32 fifo_segment_num_free_chunks (fifo_segment_t * fs, u32 size); u8 fifo_segment_get_mem_usage (fifo_segment_t * fs); fifo_segment_mem_status_t fifo_segment_get_mem_status (fifo_segment_t * fs); void fifo_segment_main_init (fifo_segment_main_t * sm, u64 baseva, u32 timeout_in_seconds); format_function_t format_fifo_segment; format_function_t format_fifo_segment_type; #endif /* __included_fifo_segment_h__ */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */