HONEYCOMB-10: jVpp - the new java API. C code and jar file generation
Added comments generation for C and Java files. Change-Id: Ifb670a5592eb871bfe68804f0a8d8f9b5b14f00a Signed-off-by: Marek Gradzki <mgradzki@cisco.com> Signed-off-by: Ed Warnicke <eaw@cisco.com>
This commit is contained in:

committed by
Ed Warnicke

parent
c5e8681b32
commit
d85036fd6b
@ -25,7 +25,11 @@ callback_template = Template("""
|
||||
package $base_package.$callback_package;
|
||||
|
||||
/**
|
||||
* $docs
|
||||
* <p>Represents callback for vpe.api message.
|
||||
* <br>It was generated by callback_gen.py based on $inputfile preparsed data:
|
||||
* <pre>
|
||||
$docs
|
||||
* </pre>
|
||||
*/
|
||||
public interface $cls_name extends $base_package.$callback_package.JVppCallback {
|
||||
|
||||
@ -38,16 +42,16 @@ global_callback_template = Template("""
|
||||
package $base_package.$callback_package;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Global aggregated callback interface
|
||||
* <p>Global aggregated callback interface.
|
||||
* <br>It was generated by callback_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public interface JVppGlobalCallback extends $callbacks {
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
def generate_callbacks(func_list, base_package, callback_package, dto_package):
|
||||
def generate_callbacks(func_list, base_package, callback_package, dto_package, inputfile):
|
||||
""" Generates callback interfaces """
|
||||
print "Generating Callback interfaces"
|
||||
|
||||
@ -73,7 +77,8 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package):
|
||||
reply_type = "%s.%s.%s" % (base_package, dto_package, camel_case_name_with_suffix)
|
||||
method = "void on{0}({1} reply);".format(camel_case_name_with_suffix, reply_type)
|
||||
callback_file.write(
|
||||
callback_template.substitute(docs='Generated from ' + str(func),
|
||||
callback_template.substitute(inputfile=inputfile,
|
||||
docs=util.api_message_to_javadoc(func),
|
||||
cls_name=camel_case_name + callback_suffix,
|
||||
callback_method=method,
|
||||
base_package=base_package,
|
||||
@ -82,7 +87,8 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package):
|
||||
callback_file.close()
|
||||
|
||||
callback_file = open(os.path.join(callback_package, "JVppGlobalCallback.java"), 'w')
|
||||
callback_file.write(global_callback_template.substitute(callbacks=", ".join(callbacks),
|
||||
callback_file.write(global_callback_template.substitute(inputfile=inputfile,
|
||||
callbacks=", ".join(callbacks),
|
||||
base_package=base_package,
|
||||
callback_package=callback_package))
|
||||
callback_file.flush()
|
||||
|
@ -20,7 +20,11 @@ dto_template = Template("""
|
||||
package $base_package.$dto_package;
|
||||
|
||||
/**
|
||||
* $docs
|
||||
* <p>This class represents $description.
|
||||
* <br>It was generated by dto_gen.py based on $inputfile preparsed data:
|
||||
* <pre>
|
||||
$docs
|
||||
* </pre>
|
||||
*/
|
||||
public final class $cls_name implements $base_package.$dto_package.$base_type {
|
||||
|
||||
@ -36,8 +40,7 @@ send_template = Template(""" @Override
|
||||
return jvpp.$method_name($args);
|
||||
}\n""")
|
||||
|
||||
|
||||
def generate_dtos(func_list, base_package, dto_package):
|
||||
def generate_dtos(func_list, base_package, dto_package, inputfile):
|
||||
""" Generates dto objects in a dedicated package """
|
||||
print "Generating DTOs"
|
||||
|
||||
@ -60,6 +63,7 @@ def generate_dtos(func_list, base_package, dto_package):
|
||||
methods = ""
|
||||
base_type = ""
|
||||
if util.is_reply(camel_case_dto_name):
|
||||
description = "vpe.api reply DTO"
|
||||
request_dto_name = get_request_name(camel_case_dto_name, func['name'])
|
||||
if util.is_details(camel_case_dto_name):
|
||||
# FIXME assumption that dump calls end with "Dump" suffix. Not enforced in vpe.api
|
||||
@ -75,11 +79,15 @@ def generate_dtos(func_list, base_package, dto_package):
|
||||
args=args)
|
||||
if util.is_dump(camel_case_dto_name):
|
||||
base_type += "JVppDump"
|
||||
description = "vpe.api dump request DTO"
|
||||
else:
|
||||
base_type += "JVppRequest"
|
||||
description = "vpe.api request DTO"
|
||||
|
||||
dto_file = open(dto_path, 'w')
|
||||
dto_file.write(dto_template.substitute(docs='Generated from ' + str(func),
|
||||
dto_file.write(dto_template.substitute(inputfile=inputfile,
|
||||
description=description,
|
||||
docs=util.api_message_to_javadoc(func),
|
||||
cls_name=camel_case_dto_name,
|
||||
fields=fields,
|
||||
methods=methods,
|
||||
@ -89,13 +97,12 @@ def generate_dtos(func_list, base_package, dto_package):
|
||||
dto_file.flush()
|
||||
dto_file.close()
|
||||
|
||||
flush_dump_reply_dtos()
|
||||
flush_dump_reply_dtos(inputfile)
|
||||
|
||||
|
||||
dump_dto_suffix = "ReplyDump"
|
||||
dump_reply_artificial_dtos = {}
|
||||
|
||||
|
||||
# Returns request name or special one from unconventional_naming_rep_req map
|
||||
def get_request_name(camel_case_dto_name, func_name):
|
||||
return util.underscore_to_camelcase_upper(
|
||||
@ -103,12 +110,14 @@ def get_request_name(camel_case_dto_name, func_name):
|
||||
else util.remove_reply_suffix(camel_case_dto_name)
|
||||
|
||||
|
||||
def flush_dump_reply_dtos():
|
||||
def flush_dump_reply_dtos(inputfile):
|
||||
for dump_reply_artificial_dto in dump_reply_artificial_dtos.values():
|
||||
dto_path = os.path.join(dump_reply_artificial_dto['dto_package'],
|
||||
dump_reply_artificial_dto['cls_name'] + ".java")
|
||||
dto_file = open(dto_path, 'w')
|
||||
dto_file.write(dto_template.substitute(docs=dump_reply_artificial_dto['docs'],
|
||||
dto_file.write(dto_template.substitute(inputfile=inputfile,
|
||||
description="vpe.api dump reply wrapper",
|
||||
docs=dump_reply_artificial_dto['docs'],
|
||||
cls_name=dump_reply_artificial_dto['cls_name'],
|
||||
fields=dump_reply_artificial_dto['fields'],
|
||||
methods=dump_reply_artificial_dto['methods'],
|
||||
@ -133,7 +142,7 @@ def generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_c
|
||||
dump_reply_artificial_dtos[request_dto_name]['fields'] = \
|
||||
dump_reply_artificial_dtos[request_dto_name]['fields'] + '\n' + fields
|
||||
else:
|
||||
dump_reply_artificial_dtos[request_dto_name] = ({'docs': 'Dump reply wrapper generated from ' + str(func),
|
||||
dump_reply_artificial_dtos[request_dto_name] = ({'docs': util.api_message_to_javadoc(func),
|
||||
'cls_name': cls_name,
|
||||
'fields': fields,
|
||||
'methods': "",
|
||||
|
330
vpp-api/java/jvpp/gen/jvpp_c_gen.py
Normal file
330
vpp-api/java/jvpp/gen/jvpp_c_gen.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,11 @@ import dto_gen
|
||||
jvpp_ifc_template = Template("""
|
||||
package $base_package.$callback_facade_package;
|
||||
|
||||
/**
|
||||
* <p>Callback Java API representation of vpe.api.
|
||||
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public interface CallbackJVpp extends java.lang.AutoCloseable {
|
||||
|
||||
@Override
|
||||
@ -36,6 +41,11 @@ $methods
|
||||
jvpp_impl_template = Template("""
|
||||
package $base_package.$callback_facade_package;
|
||||
|
||||
/**
|
||||
* <p>Default implementation of CallbackJVpp interface.
|
||||
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public final class CallbackJVppFacade implements $base_package.$callback_facade_package.CallbackJVpp {
|
||||
|
||||
private final $base_package.JVpp jvpp;
|
||||
@ -78,7 +88,7 @@ no_arg_method_impl_template = Template(""" public final void $name($base_pack
|
||||
""")
|
||||
|
||||
|
||||
def generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package):
|
||||
def generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile):
|
||||
""" Generates callback facade """
|
||||
print "Generating JVpp callback facade"
|
||||
|
||||
@ -131,7 +141,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
|
||||
join = os.path.join(callback_facade_package, "CallbackJVpp.java")
|
||||
jvpp_file = open(join, 'w')
|
||||
jvpp_file.write(
|
||||
jvpp_ifc_template.substitute(methods="\n".join(methods),
|
||||
jvpp_ifc_template.substitute(inputfile=inputfile,
|
||||
methods="\n".join(methods),
|
||||
base_package=base_package,
|
||||
dto_package=dto_package,
|
||||
callback_facade_package=callback_facade_package))
|
||||
@ -139,7 +150,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
|
||||
jvpp_file.close()
|
||||
|
||||
jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacade.java"), 'w')
|
||||
jvpp_file.write(jvpp_impl_template.substitute(methods="\n".join(methods_impl),
|
||||
jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
|
||||
methods="\n".join(methods_impl),
|
||||
base_package=base_package,
|
||||
dto_package=dto_package,
|
||||
callback_package=callback_package,
|
||||
@ -147,14 +159,16 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
|
||||
jvpp_file.flush()
|
||||
jvpp_file.close()
|
||||
|
||||
generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package)
|
||||
generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile)
|
||||
|
||||
|
||||
jvpp_facade_callback_template = Template("""
|
||||
package $base_package.$callback_facade_package;
|
||||
|
||||
/**
|
||||
* Async facade callback setting values to future objects
|
||||
* <p>JVppGlobalCallback implementation for Java Callback API.
|
||||
* <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
|
||||
|
||||
@ -185,7 +199,7 @@ jvpp_facade_callback_method_template = Template("""
|
||||
""")
|
||||
|
||||
|
||||
def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package):
|
||||
def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile):
|
||||
callbacks = []
|
||||
for func in func_list:
|
||||
|
||||
@ -204,7 +218,8 @@ def generate_callback(func_list, base_package, dto_package, callback_package, ca
|
||||
callback_dto=camel_case_name_with_suffix))
|
||||
|
||||
jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w')
|
||||
jvpp_file.write(jvpp_facade_callback_template.substitute(base_package=base_package,
|
||||
jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
|
||||
base_package=base_package,
|
||||
dto_package=dto_package,
|
||||
callback_package=callback_package,
|
||||
methods="".join(callbacks),
|
||||
|
@ -22,7 +22,9 @@ jvpp_facade_callback_template = Template("""
|
||||
package $base_package.$future_package;
|
||||
|
||||
/**
|
||||
* Async facade callback setting values to future objects
|
||||
* <p>Async facade callback setting values to future objects
|
||||
* <br>It was generated by jvpp_future_facade_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public final class FutureJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
|
||||
|
||||
@ -119,7 +121,7 @@ jvpp_facade_details_callback_method_template = Template("""
|
||||
""")
|
||||
|
||||
|
||||
def generate_jvpp(func_list, base_package, dto_package, callback_package, future_facade_package):
|
||||
def generate_jvpp(func_list, base_package, dto_package, callback_package, future_facade_package, inputfile):
|
||||
""" Generates JVpp interface and JNI implementation """
|
||||
print "Generating JVpp future facade"
|
||||
|
||||
@ -159,7 +161,8 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, future
|
||||
callback_dto=camel_case_name_with_suffix))
|
||||
|
||||
jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacadeCallback.java"), 'w')
|
||||
jvpp_file.write(jvpp_facade_callback_template.substitute(base_package=base_package,
|
||||
jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
|
||||
base_package=base_package,
|
||||
dto_package=dto_package,
|
||||
callback_package=callback_package,
|
||||
methods="".join(callbacks),
|
||||
|
131
vpp-api/java/jvpp/gen/jvpp_gen.py
Executable file
131
vpp-api/java/jvpp/gen/jvpp_gen.py
Executable file
@ -0,0 +1,131 @@
|
||||
#!/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 callback_gen
|
||||
import dto_gen
|
||||
import jvpp_callback_facade_gen
|
||||
import jvpp_future_facade_gen
|
||||
import jvpp_impl_gen
|
||||
import jvpp_c_gen
|
||||
import util
|
||||
|
||||
# Invocation:
|
||||
# ~/Projects/vpp/vpp-api/jvpp/gen$ mkdir -p java/org/openvpp/jvpp && cd java/org/openvpp/jvpp
|
||||
# ~/Projects/vpp/vpp-api/jvpp/gen/java/org/openvpp/jvpp$ ../../../../jvpp_gen.py -idefs_api_vpp_papi.py
|
||||
#
|
||||
# Compilation:
|
||||
# ~/Projects/vpp/vpp-api/jvpp/gen/java/org/openvpp/jvpp$ javac *.java dto/*.java callback/*.java
|
||||
#
|
||||
# where
|
||||
# defs_api_vpp_papi.py - vpe.api in python format (generated by vppapigen)
|
||||
from util import vpp_2_jni_type_mapping
|
||||
|
||||
parser = argparse.ArgumentParser(description='VPP Java API generator')
|
||||
parser.add_argument('-i', action="store", dest="inputfile")
|
||||
args = parser.parse_args()
|
||||
|
||||
sys.path.append(".")
|
||||
|
||||
inputfile = args.inputfile.replace('.py', '')
|
||||
cfg = importlib.import_module(inputfile, package=None)
|
||||
|
||||
|
||||
# FIXME: functions unsupported due to problems with vpe.api
|
||||
def is_supported(f_name):
|
||||
return f_name not in {'vnet_ip4_fib_counters', 'vnet_ip6_fib_counters'}
|
||||
|
||||
|
||||
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 = []
|
||||
c_types_list = []
|
||||
for i in t:
|
||||
if not filter(i[1]):
|
||||
continue
|
||||
if len(i) is 3: # array type
|
||||
types_list.append(vpp_2_jni_type_mapping[i[0]] + 'Array')
|
||||
c_types_list.append(i[0] + '[]')
|
||||
else: # primitive type
|
||||
types_list.append(vpp_2_jni_type_mapping[i[0]])
|
||||
c_types_list.append(i[0])
|
||||
return types_list, c_types_list
|
||||
|
||||
|
||||
def get_definitions():
|
||||
# Pass 1
|
||||
func_list = []
|
||||
func_name = {}
|
||||
for a in cfg.vppapidef:
|
||||
if not is_supported(a[0]):
|
||||
continue
|
||||
|
||||
java_name = util.underscore_to_camelcase(a[0])
|
||||
|
||||
# For replies include all the arguments except message_id
|
||||
if util.is_reply(java_name):
|
||||
types, c_types = 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), ('c_types', c_types)])
|
||||
# For requests skip message_id, client_id and context
|
||||
else:
|
||||
types, c_types = 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), ('c_types', c_types)])
|
||||
|
||||
# Indexed by name
|
||||
func_list.append(func_name[a[0]])
|
||||
return func_list, func_name
|
||||
|
||||
|
||||
func_list, func_name = get_definitions()
|
||||
|
||||
base_package = 'org.openvpp.jvpp'
|
||||
dto_package = 'dto'
|
||||
callback_package = 'callback'
|
||||
future_package = 'future'
|
||||
# TODO find better package name
|
||||
callback_facade_package = 'callfacade'
|
||||
|
||||
dto_gen.generate_dtos(func_list, base_package, dto_package, args.inputfile)
|
||||
jvpp_impl_gen.generate_jvpp(func_list, base_package, dto_package, args.inputfile)
|
||||
callback_gen.generate_callbacks(func_list, base_package, callback_package, dto_package, args.inputfile)
|
||||
jvpp_c_gen.generate_jvpp(func_list, args.inputfile)
|
||||
jvpp_future_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, future_package, args.inputfile)
|
||||
jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package, args.inputfile)
|
@ -19,6 +19,12 @@ from string import Template
|
||||
jvpp_ifc_template = Template("""
|
||||
package $base_package;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java representation of vpe.api.
|
||||
* <br>It was generated by jvpp_impl_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public interface JVpp extends java.lang.AutoCloseable {
|
||||
|
||||
/**
|
||||
@ -36,6 +42,11 @@ $methods
|
||||
jvpp_impl_template = Template("""
|
||||
package $base_package;
|
||||
|
||||
/**
|
||||
* <p>Default implementation of JVpp interface.
|
||||
* <br>It was generated by jvpp_impl_gen.py based on $inputfile
|
||||
* <br>(python representation of vpe.api generated by vppapigen).
|
||||
*/
|
||||
public final class JVppImpl implements $base_package.JVpp {
|
||||
|
||||
private final $base_package.VppConnection connection;
|
||||
@ -82,7 +93,7 @@ no_arg_method_impl_template = Template(""" public final int $name() {
|
||||
""")
|
||||
|
||||
|
||||
def generate_jvpp(func_list, base_package, dto_package):
|
||||
def generate_jvpp(func_list, base_package, dto_package, inputfile):
|
||||
""" Generates JVpp interface and JNI implementation """
|
||||
print "Generating JVpp"
|
||||
|
||||
@ -126,14 +137,16 @@ def generate_jvpp(func_list, base_package, dto_package):
|
||||
|
||||
jvpp_file = open("JVpp.java", 'w')
|
||||
jvpp_file.write(
|
||||
jvpp_ifc_template.substitute(methods="\n".join(methods),
|
||||
jvpp_ifc_template.substitute(inputfile=inputfile,
|
||||
methods="\n".join(methods),
|
||||
base_package=base_package,
|
||||
dto_package=dto_package))
|
||||
jvpp_file.flush()
|
||||
jvpp_file.close()
|
||||
|
||||
jvpp_file = open("JVppImpl.java", 'w')
|
||||
jvpp_file.write(jvpp_impl_template.substitute(methods="\n".join(methods_impl),
|
||||
jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
|
||||
methods="\n".join(methods_impl),
|
||||
base_package=base_package,
|
||||
dto_package=dto_package))
|
||||
jvpp_file.flush()
|
||||
|
@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import os, pprint
|
||||
from os import removedirs
|
||||
|
||||
|
||||
@ -171,3 +171,8 @@ def remove_suffix(camel_case_name_with_suffix, suffix):
|
||||
|
||||
def is_control_ping(camel_case_name_with_suffix):
|
||||
return "controlping" in camel_case_name_with_suffix.lower()
|
||||
|
||||
def api_message_to_javadoc(api_message):
|
||||
""" Converts vpe.api message description to javadoc """
|
||||
str = pprint.pformat(api_message, indent=4, width=120, depth=None)
|
||||
return " * " + str.replace("\n", "\n * ")
|
Reference in New Issue
Block a user