]> asedeno.scripts.mit.edu Git - cl-protobufs.git/blobdiff - parser.lisp
Update documentation
[cl-protobufs.git] / parser.lisp
index 991181bce2af3d1a4afa37a5d2f0fc1ceb1d8b19..26c72053905756e254ddbfeb07c85595b9fea72e 100644 (file)
@@ -2,7 +2,7 @@
 ;;;                                                                  ;;;
 ;;; Free Software published under an MIT-like license. See LICENSE   ;;;
 ;;;                                                                  ;;;
-;;; Copyright (c) 2012 Google, Inc.  All rights reserved.            ;;;
+;;; Copyright (c) 2012-2013 Google, Inc.  All rights reserved.       ;;;
 ;;;                                                                  ;;;
 ;;; Original author: Scott McKay                                     ;;;
 ;;;                                                                  ;;;
                    :class class
                    :name  name))
          (*protobuf* schema)
-         (*protobuf-package* *package*)
+         *protobuf-package*
+         *protobuf-rpc-package*
          (*protobuf-conc-name* conc-name))
-    (loop
-      (skip-whitespace stream)
-      (maybe-skip-comments stream)
-      (let ((char (peek-char nil stream nil)))
-        (cond ((null char)
-               (remove-options schema "lisp_package")
-               (resolve-lisp-names schema)
-               (return-from parse-schema-from-stream schema))
-              ((proto-token-char-p char)
-               (let ((token (parse-token stream)))
-                 (cond ((string= token "syntax")
-                        (parse-proto-syntax stream schema))
-                       ((string= token "package")
-                        (parse-proto-package stream schema))
-                       ((string= token "import")
-                        (parse-proto-import stream schema))
-                       ((string= token "option")
-                        (let* ((option (parse-proto-option stream schema))
-                               (name   (and option (proto-name option)))
-                               (value  (and option (proto-value option))))
-                          (when (and option (option-name= name "lisp_package"))
-                            (set-lisp-package schema value))))
-                       ((string= token "enum")
-                        (parse-proto-enum stream schema))
-                       ((string= token "extend")
-                        (parse-proto-extend stream schema))
-                       ((string= token "message")
-                        (parse-proto-message stream schema))
-                       ((string= token "service")
-                        (parse-proto-service stream schema)))))
-              (t
-               (error "Syntax error at position ~D" (file-position stream))))))))
+    (labels ((ensure-package ()
+               "Find a fallback for our Lisp package if we don't have an obvious one already.
+                * java_package
+                * *package*"
+               (unless *protobuf-package*
+                 (let ((java-package (find-option schema "java_package")))
+                   (if java-package
+                       (set-lisp-package schema java-package)
+                       (setq *protobuf-package* *package*)))))
+             (ensure-rpc-package ()
+               (ensure-package)
+               (unless *protobuf-rpc-package*
+                 (let ((rpc-package-name (format nil "~A-~A" (package-name *protobuf-package*) 'rpc)))
+                   (setq *protobuf-rpc-package*
+                         (or (find-proto-package rpc-package-name)
+                             (make-package (string-upcase rpc-package-name) :use ())))))))
+      (loop
+        (skip-whitespace stream)
+        (maybe-skip-comments stream)
+        (let ((char (peek-char nil stream nil)))
+          (cond ((null char)
+                 (remove-options schema "lisp_package")
+                 (resolve-lisp-names schema)
+                 (return-from parse-schema-from-stream schema))
+                ((proto-token-char-p char)
+                 (let ((token (parse-token stream)))
+                   (cond ((string= token "syntax")
+                          (parse-proto-syntax stream schema))
+                         ((string= token "package")
+                          (parse-proto-package stream schema))
+                         ((string= token "import")
+                          (parse-proto-import stream schema))
+                         ((string= token "option")
+                          (let* ((option (parse-proto-option stream schema))
+                                 (name   (and option (proto-name option)))
+                                 (value  (and option (proto-value option))))
+                            (when (and option (option-name= name "lisp_package"))
+                              (set-lisp-package schema value))))
+                         ((string= token "enum")
+                          (ensure-package)
+                          (parse-proto-enum stream schema))
+                         ((string= token "extend")
+                          (ensure-package)
+                          (parse-proto-extend stream schema))
+                         ((string= token "message")
+                          (ensure-package)
+                          (parse-proto-message stream schema))
+                         ((string= token "service")
+                          (ensure-rpc-package)
+                          (parse-proto-service stream schema)))))
+                (t
+                 (error "Syntax error at position ~D" (file-position stream)))))))))
 
 (defun set-lisp-package (schema lisp-package-name)
   "Set the package for generated lisp names of 'schema'."
                          :class (proto-class message)
                          :name  (proto-name message)
                          :qualified-name (proto-qualified-name message)
-                         :parent (proto-parent message)
+                         :parent protobuf
                          :alias-for (proto-alias-for message)
                          :conc-name (proto-conc-name message)
                          :enums    (copy-list (proto-enums message))
          (out  (prog2 (expect-char stream #\( () "service")
                    (parse-token stream)
                  (expect-char stream #\) () "service")))
-         (opts (let ((opts (parse-proto-method-options stream)))
-                 (when (or (null opts) (eql (peek-char nil stream nil) #\;))
+         (opts (multiple-value-bind (opts bodyp)
+                   (parse-proto-method-options stream)
+                 (when (or (not bodyp) (eql (peek-char nil stream nil) #\;))
                    (expect-char stream #\; () "service"))
                  (maybe-skip-comments stream)
                  opts))
            (stub (or (and name (make-lisp-symbol name))
                      stub)))
       (setf (proto-class method) stub
-            (proto-client-stub method) stub
-            (proto-server-stub method) (intern (format nil "~A-~A" 'do stub) *protobuf-package*)))
+            (proto-client-stub method) (intern (format nil "~A-~A" 'call stub) *protobuf-rpc-package*)
+            (proto-server-stub method) (intern (format nil "~A-~A" stub 'impl) *protobuf-rpc-package*)))
     (let ((strm (find-option method "stream_type")))
       (when strm
         (setf (proto-streams-name method) strm)))
 
 (defun parse-proto-method-options (stream)
   "Parse any options in a Protobufs method from 'stream'.
-   Returns a list of 'protobuf-option' objects."
+   Returns a list of 'protobuf-option' objects.
+   If a body was parsed, returns a second value T."
   (when (eql (peek-char nil stream nil) #\{)
     (expect-char stream #\{ () "service")
     (maybe-skip-comments stream)
         (collect-option (parse-proto-option stream nil)))
       (expect-char stream #\} '(#\;) "service")
       (maybe-skip-comments stream)
-      options)))
+      (values options t))))