-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #214 from mransan/wip-typecheck-services
typecheck and codegen for services
- Loading branch information
Showing
60 changed files
with
1,887 additions
and
276 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
#include <caml/alloc.h> | ||
#include <caml/memory.h> | ||
#include <caml/mlvalues.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
inline int pbrt_varint_size(int64_t i) { | ||
int n = 0; | ||
while (1) { | ||
n++; | ||
int64_t cur = i & 0x7f; | ||
if (cur == i) | ||
break; | ||
i = i >> 7; | ||
} | ||
return n; | ||
} | ||
|
||
// number of bytes for i | ||
CAMLprim value caml_pbrt_varint_size(int64_t i) { | ||
int res = pbrt_varint_size(i); | ||
return Val_int(res); | ||
} | ||
|
||
CAMLprim value caml_pbrt_varint_size_byte(value v_i) { | ||
CAMLparam1(v_i); | ||
|
||
int64_t i = Int64_val(v_i); | ||
int res = pbrt_varint_size(i); | ||
CAMLreturn(Val_int(res)); | ||
} | ||
|
||
// write i at str[idx…] | ||
inline void pbrt_varint(unsigned char *str, int64_t i) { | ||
while (true) { | ||
int64_t cur = i & 0x7f; | ||
if (cur == i) { | ||
*str = (unsigned char)cur; | ||
break; | ||
} else { | ||
*str = (unsigned char)(cur | 0x80); | ||
i = i >> 7; | ||
++str; | ||
} | ||
} | ||
} | ||
|
||
// let[@inline] varint (i : int64) (e : t) : unit = | ||
// let n_bytes = varint_size i in | ||
// let start = reserve_n e n_bytes in | ||
// | ||
// let i = ref i in | ||
// for j = 0 to n_bytes - 1 do | ||
// let cur = Int64.(logand !i 0x7fL) in | ||
// if j = n_bytes - 1 then | ||
// Bytes.set e.b (start + j) (Char.unsafe_chr Int64.(to_int cur)) | ||
// else ( | ||
// Bytes.set e.b (start + j) | ||
// (Char.unsafe_chr Int64.(to_int (logor 0x80L cur))); | ||
// i := Int64.shift_right_logical !i 7 | ||
// ) | ||
// done | ||
|
||
// write `i` starting at `idx` | ||
CAMLprim value caml_pbrt_varint(value _str, intnat idx, int64_t i) { | ||
CAMLparam1(_str); | ||
char *str = Bytes_val(_str); | ||
pbrt_varint(str + idx, i); | ||
CAMLreturn(Val_unit); | ||
} | ||
|
||
CAMLprim value caml_pbrt_varint_bytes(value _str, value _idx, value _i) { | ||
CAMLparam3(_str, _idx, _i); | ||
char *str = Bytes_val(_str); | ||
int idx = Int_val(_idx); | ||
int64_t i = Int64_val(_idx); | ||
pbrt_varint(str + idx, i); | ||
CAMLreturn(Val_unit); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,8 @@ | |
(generate_opam_files true) | ||
(version 2.4) | ||
|
||
(maintainers "Maxime Ransan <[email protected]>") | ||
(authors "Maxime Ransan <[email protected]>") | ||
(maintainers "Maxime Ransan <[email protected]>" "Simon Cruanes") | ||
(authors "Maxime Ransan <[email protected]>" "Simon Cruanes") | ||
(source (github mransan/ocaml-protoc)) | ||
(license MIT) | ||
|
||
|
@@ -20,7 +20,7 @@ | |
(package | ||
(name pbrt) | ||
(synopsis "Runtime library for Protobuf tooling") | ||
(depends | ||
(depends | ||
stdlib-shims | ||
(odoc :with-doc) | ||
(ocaml (>= 4.03))) | ||
|
@@ -29,11 +29,19 @@ | |
(package | ||
(name pbrt_yojson) | ||
(synopsis "Runtime library for ocaml-protoc to support JSON encoding/decoding") | ||
(depends | ||
(depends | ||
(ocaml (>= 4.03)) | ||
(odoc :with-doc) | ||
(yojson (>= 1.6)) | ||
base64) | ||
(tags (protobuf encode decode))) | ||
|
||
(package | ||
(name pbrt_services) | ||
(synopsis "Runtime library for ocaml-protoc to support RPC services") | ||
(depends | ||
(ocaml (>= 4.03)) | ||
(pbrt (= :version)) | ||
(pbrt_yojson (= :version))) | ||
(tags (protobuf encode decode services rpc))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,8 @@ | |
opam-version: "2.0" | ||
version: "2.4" | ||
synopsis: "Pure OCaml compiler for .proto files" | ||
maintainer: ["Maxime Ransan <[email protected]>"] | ||
authors: ["Maxime Ransan <[email protected]>"] | ||
maintainer: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
authors: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
license: "MIT" | ||
tags: ["protoc" "protobuf" "codegen"] | ||
homepage: "https://github.com/mransan/ocaml-protoc" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,8 @@ | |
opam-version: "2.0" | ||
version: "2.4" | ||
synopsis: "Runtime library for Protobuf tooling" | ||
maintainer: ["Maxime Ransan <[email protected]>"] | ||
authors: ["Maxime Ransan <[email protected]>"] | ||
maintainer: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
authors: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
license: "MIT" | ||
tags: ["protobuf" "encode" "decode"] | ||
homepage: "https://github.com/mransan/ocaml-protoc" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# This file is generated by dune, edit dune-project instead | ||
opam-version: "2.0" | ||
version: "2.4" | ||
synopsis: "Runtime library for ocaml-protoc to support RPC services" | ||
maintainer: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
authors: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
license: "MIT" | ||
tags: ["protobuf" "encode" "decode" "services" "rpc"] | ||
homepage: "https://github.com/mransan/ocaml-protoc" | ||
bug-reports: "https://github.com/mransan/ocaml-protoc/issues" | ||
depends: [ | ||
"dune" {>= "2.0"} | ||
"ocaml" {>= "4.03"} | ||
"pbrt" {= version} | ||
"pbrt_yojson" {= version} | ||
] | ||
build: [ | ||
["dune" "subst"] {pinned} | ||
[ | ||
"dune" | ||
"build" | ||
"-p" | ||
name | ||
"-j" | ||
jobs | ||
"@install" | ||
"@runtest" {with-test} | ||
"@doc" {with-doc} | ||
] | ||
] | ||
dev-repo: "git+https://github.com/mransan/ocaml-protoc.git" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,8 @@ opam-version: "2.0" | |
version: "2.4" | ||
synopsis: | ||
"Runtime library for ocaml-protoc to support JSON encoding/decoding" | ||
maintainer: ["Maxime Ransan <[email protected]>"] | ||
authors: ["Maxime Ransan <[email protected]>"] | ||
maintainer: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
authors: ["Maxime Ransan <[email protected]>" "Simon Cruanes"] | ||
license: "MIT" | ||
tags: ["protobuf" "encode" "decode"] | ||
homepage: "https://github.com/mransan/ocaml-protoc" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
(* | ||
The MIT License (MIT) | ||
Copyright (c) 2016 Maxime Ransan <[email protected]> | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
|
@@ -29,6 +29,7 @@ module F = Pb_codegen_formatting | |
module Plugin = Pb_codegen_plugin | ||
|
||
type codegen_f = Plugin.codegen_f | ||
type codegen_service_f = Ot.service -> F.scope -> unit | ||
|
||
type ocaml_mod = { | ||
ml: F.scope; | ||
|
@@ -88,16 +89,32 @@ let generate_for_all_types (ocaml_types : Ot.type_ list list) (sc : F.scope) | |
()) | ||
ocaml_types | ||
|
||
let generate_for_all_services (services : Ot.service list) (sc : F.scope) | ||
(f : codegen_service_f) ocamldoc_title : unit = | ||
(match ocamldoc_title with | ||
| None -> () | ||
| Some ocamldoc_title -> | ||
F.empty_line sc; | ||
F.linep sc "(** {2 %s} *)" ocamldoc_title; | ||
F.empty_line sc); | ||
|
||
List.iter (fun (service : Ot.service) -> f service sc) services | ||
|
||
let generate_type_and_default (self : ocaml_mod) ocaml_types : unit = | ||
generate_for_all_types ocaml_types self.ml Pb_codegen_types.gen_struct None; | ||
generate_for_all_types ocaml_types self.ml Pb_codegen_default.gen_struct None; | ||
|
||
generate_for_all_types ocaml_types self.mli Pb_codegen_types.gen_sig | ||
(Some Pb_codegen_types.ocamldoc_title); | ||
generate_for_all_types ocaml_types self.mli Pb_codegen_default.gen_sig | ||
(Some Pb_codegen_default.ocamldoc_title); | ||
() | ||
|
||
let generate_make (self : ocaml_mod) ocaml_types : unit = | ||
generate_for_all_types ocaml_types self.ml Pb_codegen_make.gen_struct | ||
(Some Pb_codegen_make.ocamldoc_title); | ||
generate_for_all_types ocaml_types self.mli Pb_codegen_make.gen_sig | ||
(Some Pb_codegen_make.ocamldoc_title) | ||
|
||
let generate_mutable_records (self : ocaml_mod) ocaml_types : unit = | ||
let ocaml_types = List.flatten ocaml_types in | ||
List.iter | ||
|
@@ -111,6 +128,17 @@ let generate_mutable_records (self : ocaml_mod) ocaml_types : unit = | |
| _ -> ()) | ||
ocaml_types | ||
|
||
let generate_service_struct service sc : unit = | ||
Pb_codegen_services.gen_service_struct service sc | ||
|
||
let generate_service_sig service sc : unit = | ||
Pb_codegen_services.gen_service_sig service sc | ||
|
||
let generate_services (self : ocaml_mod) services : unit = | ||
generate_for_all_services services self.ml generate_service_struct None; | ||
generate_for_all_services services self.mli generate_service_sig | ||
(Some "Services") | ||
|
||
let generate_plugin (self : ocaml_mod) ocaml_types (p : Plugin.t) : unit = | ||
let (module P) = p in | ||
F.line self.ml "[@@@ocaml.warning \"-27-30-39\"]"; | ||
|
@@ -119,11 +147,15 @@ let generate_plugin (self : ocaml_mod) ocaml_types (p : Plugin.t) : unit = | |
generate_for_all_types ocaml_types self.mli P.gen_sig (Some P.ocamldoc_title); | ||
() | ||
|
||
let codegen ocaml_types ~proto_file_options ~proto_file_name | ||
(plugins : Plugin.t list) : ocaml_mod = | ||
let codegen (proto : Ot.proto) ~generate_make:gen_make ~proto_file_options | ||
~proto_file_name (plugins : Plugin.t list) : ocaml_mod = | ||
let self = new_ocaml_mod ~proto_file_options ~proto_file_name () in | ||
generate_type_and_default self ocaml_types; | ||
generate_type_and_default self proto.proto_types; | ||
if List.exists Pb_codegen_plugin.requires_mutable_records plugins then | ||
generate_mutable_records self ocaml_types; | ||
List.iter (generate_plugin self ocaml_types) plugins; | ||
generate_mutable_records self proto.proto_types; | ||
if gen_make then generate_make self proto.proto_types; | ||
List.iter (generate_plugin self proto.proto_types) plugins; | ||
|
||
(* services come last, they need binary and json *) | ||
generate_services self proto.proto_services; | ||
self |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.