From a12d68af32fc30164b0486675cfd1405ebea3f0f Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Wed, 25 Apr 2012 16:46:05 +0000 Subject: [PATCH] Get 'import' working before this all goes prime-time git-svn-id: http://svn.internal.itasoftware.com/svn/ita/branches/qres/swm/borgify-1/qres/lisp/quux/protobufs@540933 f8382938-511b-0410-9cdd-bb47b084005c --- asdf-support.lisp | 35 +++++++++++++++++++++++++++++++++++ define-proto.lisp | 5 +++-- model-classes.lisp | 6 +++--- parser.lisp | 4 ++-- printer.lisp | 2 +- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/asdf-support.lisp b/asdf-support.lisp index c99dfa9..0cb1e29 100644 --- a/asdf-support.lisp +++ b/asdf-support.lisp @@ -46,3 +46,38 @@ :if-exists :replace) (write-protobuf protobuf :stream stream :type :lisp))) lisp-file) + + +;; Process 'import' lines +(defun process-imports (&rest imports) + "Imports all of the files given by 'imports'. + If the file is a .proto file, it first parses it and writes a .lisp file. + The .lisp file is the compiled and loaded." + (dolist (import imports) + (let* ((base-file (pathname import)) + (proto-file (make-pathname :type "proto" :defaults base-file)) + (lisp-file (make-pathname :name (pathname-name base-file) :type "lisp" + :defaults (or *compile-file-pathname* base-file))) + (fasl-file (compile-file-pathname lisp-file)) + (proto-date (and (probe-file proto-file) + (ignore-errors (file-write-date proto-file)))) + (lisp-date (and (probe-file lisp-file) + (ignore-errors (file-write-date lisp-file)))) + (fasl-date (and (probe-file fasl-file) + (ignore-errors (file-write-date fasl-file))))) + (when (string= (pathname-type base-file) "proto") + ;; The user asked to import a .proto file + ;; If there's no .lisp file or an older .lisp file, parse the .proto file now + (cond ((not proto-date) + (warn "Could not find the file to be imported ~A" proto-file)) + ((or (not lisp-date) + (< lisp-date proto-date)) + (parse-protobuf-file proto-file lisp-file) + (setq lisp-date (file-write-date lisp-file))))) + ;; Compile the .lisp file, if necessary + (when (or (not fasl-date) + (< fasl-date lisp-date)) + (setq fasl-file (compile-file lisp-file)) + (setq fasl-date (file-write-date fasl-file))) + ;; Now we can load the .fasl file + (load fasl-file)))) diff --git a/define-proto.lisp b/define-proto.lisp index edddf87..5f5bb61 100644 --- a/define-proto.lisp +++ b/define-proto.lisp @@ -34,20 +34,21 @@ collect (make-instance 'protobuf-option :name key :value val))) + (imports (if (listp import) import (list import))) (protobuf (make-instance 'protobuf :class type :name name :syntax (or syntax "proto2") :package package :lisp-package (or lisp-pkg package) - ;;---*** This needs to parse the imported file(s) - :imports (if (listp import) import (list import)) + :imports imports :options options :optimize optimize :documentation documentation)) (*protobuf* protobuf) (*protobuf-package* (or (find-package lisp-pkg) (find-package (string-upcase lisp-pkg))))) + (apply #'process-imports imports) (with-collectors ((forms collect-form)) (dolist (msg messages) (assert (and (listp msg) diff --git a/model-classes.lisp b/model-classes.lisp index d546694..31bb3c7 100644 --- a/model-classes.lisp +++ b/model-classes.lisp @@ -147,8 +147,8 @@ (find type (proto-enums protobuf) :key #'proto-name :test #'string=)) -;;--- For now, we support only the built-in options -;;--- We will want to extend this to customizable options as well +;; We accept and store any option, but only act on a few: default, packed, +;; optimize_for, lisp_package, lisp_name, lisp_alias (defclass protobuf-option (abstract-protobuf) ((name :type string ;the key :reader proto-name @@ -305,7 +305,7 @@ ;; A protobuf field within a message -;;--- Support the 'deprecated' option (should serialization ignore such fields?) +;;--- Support the 'deprecated' option (have serialization ignore such fields?) (defclass protobuf-field (base-protobuf) ((type :type string ;the name of the Protobuf type for the field :accessor proto-type diff --git a/parser.lisp b/parser.lisp index a1a854c..9ec9baa 100644 --- a/parser.lisp +++ b/parser.lisp @@ -167,7 +167,7 @@ :element-type 'character) (parse-protobuf-from-stream stream :name (class-name->proto (pathname-name (pathname stream))) - :class (pathname-name (pathname stream))))) + :class (kintern (pathname-name (pathname stream)))))) ;; The syntax for Protocol Buffers is so simple that it doesn't seem worth ;; writing a sophisticated parser @@ -252,7 +252,7 @@ (let ((import (prog1 (parse-string stream) (expect-char stream terminator "package") (maybe-skip-comments stream)))) - ;;---*** This needs to parse the imported file(s) + (process-imports import) (setf (proto-imports protobuf) (nconc (proto-imports protobuf) (list import))))) (defun parse-proto-option (stream protobuf &optional (terminator #\;)) diff --git a/printer.lisp b/printer.lisp index e3a96fc..10f1032 100644 --- a/printer.lisp +++ b/printer.lisp @@ -220,7 +220,7 @@ (find-package (string-upcase lisp-pkg)))) (*package* (or *protobuf-package* *package*))) (when (or lisp-pkg pkg) - (format stream "~&(in-package \"~A\")~%~%" (or lisp-pkg pkg))) + (format stream "~&(in-package \"~A\")~%~%" (string-upcase (or lisp-pkg pkg)))) (when documentation (write-protobuf-documentation type documentation stream :indentation indentation)) (format stream "~&(proto:define-proto ~(~A~)" (or class name)) -- 2.45.2