Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate ABAP type #14

Merged
merged 19 commits into from
Aug 18, 2023
Merged
2 changes: 1 addition & 1 deletion abaplint.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
}
],
"syntax": {
"version": "v740sp02",
"version": "v750",
"errorNamespace": "."
},
"rules": {
Expand Down
2 changes: 1 addition & 1 deletion abaplint_downport.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}
],
"syntax": {
"version": "v702",
"version": "open-abap",
"errorNamespace": ""
},
"rules": {
Expand Down
42 changes: 21 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
},
"homepage": "https://github.com/heliconialabs/abap-protobuf#readme",
"devDependencies": {
"@abaplint/cli": "^2.102.22",
"@abaplint/runtime": "^2.7.74",
"@abaplint/transpiler-cli": "^2.7.74"
"@abaplint/cli": "^2.102.24",
"@abaplint/runtime": "^2.7.75",
"@abaplint/transpiler-cli": "^2.7.75"
}
}
10 changes: 10 additions & 0 deletions src/generator/package.devc.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<DEVC>
<CTEXT>abap-protobuf</CTEXT>
</DEVC>
</asx:values>
</asx:abap>
</abapGit>
95 changes: 95 additions & 0 deletions src/generator/zcl_protobuf_generator.clas.abap
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
CLASS zcl_protobuf_generator DEFINITION PUBLIC.
PUBLIC SECTION.
CLASS-METHODS generate
IMPORTING
io_file TYPE REF TO zcl_protobuf2_file
RETURNING
VALUE(rv_abap) TYPE string.
PROTECTED SECTION.
PRIVATE SECTION.
CLASS-METHODS message
IMPORTING
io_message TYPE REF TO zcl_protobuf2_message
RETURNING
VALUE(rv_abap) TYPE string.
CLASS-METHODS enum
IMPORTING
io_enum TYPE REF TO zcl_protobuf2_enum
RETURNING
VALUE(rv_abap) TYPE string.
CLASS-METHODS field
IMPORTING
io_field TYPE REF TO zcl_protobuf2_field
RETURNING
VALUE(rv_abap) TYPE string.
ENDCLASS.



CLASS zcl_protobuf_generator IMPLEMENTATION.

METHOD generate.

rv_abap = rv_abap && |TYPES int32 TYPE i.\n|.
rv_abap = rv_abap && |TYPES uint32 TYPE int8.\n|.
rv_abap = rv_abap && |TYPES uint64 TYPE int8.\n|. " hmm
rv_abap = rv_abap && |TYPES bool TYPE abap_bool.\n|.
rv_abap = rv_abap && |TYPES bytes TYPE xstring.\n|.
rv_abap = rv_abap && |TYPES double TYPE f.\n|.
rv_abap = rv_abap && |TYPES float TYPE f.\n|.

LOOP AT io_file->mt_artefacts INTO DATA(lo_artefact).
CASE TYPE OF lo_artefact.
WHEN TYPE zcl_protobuf2_message INTO DATA(lo_message).
rv_abap = rv_abap && message( lo_message ).
WHEN OTHERS.
ASSERT 1 = 'todo'.
ENDCASE.
ENDLOOP.

ENDMETHOD.

METHOD message.

* do the nested messages and types first, if any
LOOP AT io_message->mt_artefacts INTO DATA(lo_artefact).
CASE TYPE OF lo_artefact.
WHEN TYPE zcl_protobuf2_message INTO DATA(lo_message).
rv_abap = rv_abap && message( lo_message ).
WHEN TYPE zcl_protobuf2_enum INTO DATA(lo_enum).
rv_abap = rv_abap && enum( lo_enum ).
WHEN OTHERS.
CONTINUE.
ENDCASE.
ENDLOOP.

rv_abap = rv_abap && |TYPES: BEGIN OF { io_message->mv_name },\n|.

LOOP AT io_message->mt_artefacts INTO lo_artefact.
CASE TYPE OF lo_artefact.
WHEN TYPE zcl_protobuf2_field INTO DATA(lo_field).
rv_abap = rv_abap && field( lo_field ).
WHEN OTHERS.
CONTINUE.
ENDCASE.
ENDLOOP.

rv_abap = rv_abap && | END OF { io_message->mv_name }.\n|.

ENDMETHOD.

METHOD enum.

rv_abap = |TYPES: BEGIN OF ENUM { io_enum->mv_name },\n|.
LOOP AT io_enum->mt_fields INTO DATA(ls_field).
rv_abap = rv_abap && | { ls_field-name },\n|.
ENDLOOP.
rv_abap = rv_abap && | END OF ENUM { io_enum->mv_name }.\n|.

ENDMETHOD.

METHOD field.
" todo, handle repeated
rv_abap = | { io_field->mv_field_name } TYPE { io_field->mv_type },\n|.
ENDMETHOD.
ENDCLASS.
36 changes: 36 additions & 0 deletions src/generator/zcl_protobuf_generator.clas.testclasses.abap
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CLASS ltcl_test DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS FINAL.
PRIVATE SECTION.
METHODS test FOR TESTING RAISING cx_static_check.
ENDCLASS.

CLASS ltcl_test IMPLEMENTATION.

METHOD test.

DATA(lv_proto) =
|syntax = "proto2";\n| &&
|message Person \{\n| &&
| required string name = 1;\n| &&
| required int32 id = 2;\n| &&
| optional string email = 3;\n| &&
| enum PhoneType \{\n| &&
| MOBILE = 0;\n| &&
| HOME = 1;\n| &&
| WORK = 2;\n| &&
| \}\n| &&
| message PhoneNumber \{\n| &&
| required string number = 1;\n| &&
| optional PhoneType type = 2 [default = HOME];\n| &&
| \}\n| &&
| repeated PhoneNumber phones = 4;\n| &&
|\}\n| &&
|message AddressBook \{\n| &&
| repeated Person people = 1;\n| &&
|\}|.

DATA(lv_abap) = zcl_protobuf_generator=>generate( zcl_protobuf2_parser=>parse( lv_proto ) ).
WRITE / lv_abap.

ENDMETHOD.

ENDCLASS.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_PROTOBUF</CLSNAME>
<CLSNAME>ZCL_PROTOBUF_GENERATOR</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>ZCL_PROTOBUF</DESCRIPT>
<DESCRIPT>ZCL_PROTOBUF_GENERATOR</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
Expand Down
2 changes: 1 addition & 1 deletion src/model/zcl_protobuf2_enum.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CLASS zcl_protobuf2_enum IMPLEMENTATION.
lv_spaces = repeat(
val = | |
occ = iv_nesting ).
rv_string = rv_string && lv_spaces && |}|.
rv_string = rv_string && lv_spaces && |\}|.
ENDMETHOD.

ENDCLASS.
4 changes: 2 additions & 2 deletions src/model/zcl_protobuf2_enum.clas.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
Expand All @@ -13,4 +13,4 @@
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>
</abapGit>
4 changes: 2 additions & 2 deletions src/model/zcl_protobuf2_field.clas.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
Expand All @@ -13,4 +13,4 @@
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>
</abapGit>
2 changes: 1 addition & 1 deletion src/model/zcl_protobuf2_message.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CLASS zcl_protobuf2_message IMPLEMENTATION.
lv_spaces = repeat(
val = | |
occ = iv_nesting ).
rv_string = rv_string && lv_spaces && |}|.
rv_string = rv_string && lv_spaces && |\}|.
ENDMETHOD.

ENDCLASS.
2 changes: 1 addition & 1 deletion src/model/zif_protobuf2_artefact.intf.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
Expand Down
8 changes: 7 additions & 1 deletion src/parser/zcl_protobuf2_parser.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ ENDCLASS.

CLASS zcl_protobuf2_parser IMPLEMENTATION.


METHOD enum.
* https://protobuf.dev/reference/protobuf/proto2-spec/#enum_definition
ro_enum = NEW #( io_stream->take_token( ) ).
Expand All @@ -59,6 +60,7 @@ CLASS zcl_protobuf2_parser IMPLEMENTATION.

ENDMETHOD.


METHOD field.
* https://protobuf.dev/reference/protobuf/proto2-spec/#fields

Expand All @@ -72,6 +74,7 @@ CLASS zcl_protobuf2_parser IMPLEMENTATION.
ro_field->mv_options = io_stream->get( ).
ENDMETHOD.


METHOD message.
* https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#message_definition
ro_message = NEW #( io_stream->take_token( ) ).
Expand Down Expand Up @@ -112,6 +115,7 @@ CLASS zcl_protobuf2_parser IMPLEMENTATION.
ro_file = traverse( NEW lcl_stream( lv_proto ) ).
ENDMETHOD.


METHOD remove_comments.
DATA lv_start TYPE i.
DATA lv_end TYPE i.
Expand All @@ -131,18 +135,20 @@ CLASS zcl_protobuf2_parser IMPLEMENTATION.
rv_output = rv_output(lv_start) && rv_output+lv_end.
ENDWHILE.


SPLIT rv_output AT |\n| INTO TABLE DATA(lt_lines).
LOOP AT lt_lines ASSIGNING FIELD-SYMBOL(<lv_line>).
FIND FIRST OCCURRENCE OF '//' IN <lv_line> MATCH OFFSET lv_start.
IF sy-subrc = 0.
<lv_line> = <lv_line>(lv_start).
ENDIF.
ENDLOOP.
CONCATENATE LINES OF lt_lines INTO rv_output SEPARATED BY |\n|.
CONCATENATE LINES OF lt_lines INTO rv_output SEPARATED BY cl_abap_char_utilities=>newline.

CONDENSE rv_output.
ENDMETHOD.


METHOD traverse.
* https://developers.google.com/protocol-buffers/docs/reference/proto2-spec#proto_file

Expand Down
6 changes: 4 additions & 2 deletions src/parser/zcl_protobuf2_parser.clas.locals_imp.abap
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CLASS lcl_stream IMPLEMENTATION.
ENDMETHOD.

METHOD is_empty.
rv_empty = boolc( strlen( condense( mv_str ) ) = 0 ).
rv_empty = xsdbool( strlen( condense( mv_str ) ) = 0 ).
ENDMETHOD.

METHOD take_token.
Expand Down Expand Up @@ -52,11 +52,13 @@ CLASS lcl_stream IMPLEMENTATION.

METHOD take_statement.
DATA lv_offset TYPE i.
DATA lv_tmp TYPE string.

FIND FIRST OCCURRENCE OF |;| IN mv_str MATCH OFFSET lv_offset.
ASSERT sy-subrc = 0.

ro_stream = NEW #( mv_str(lv_offset) ).
lv_tmp = mv_str(lv_offset).
ro_stream = NEW #( lv_tmp ).

lv_offset = lv_offset + 1.
mv_str = mv_str+lv_offset.
Expand Down
Loading
Loading