(lisp-pkg (and lisp-package (if (stringp lisp-package) lisp-package (string lisp-package))))
(options (remove-options
(loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val))
"optimize_for" "lisp_package"))
(imports (if (listp import) import (list import)))
(schema (make-instance 'protobuf-schema
:lisp-package (or lisp-pkg (substitute #\- #\_ package))
:imports imports
:options (if optimize
- (append options (list (make-instance 'protobuf-option
- :name "optimize_for"
- :value (if (eq optimize :speed) "SPEED" "CODE_SIZE")
- :type 'symbol)))
+ (append options
+ (list (make-option "optimize_for" (if (eq optimize :speed) "SPEED" "CODE_SIZE") 'symbol)))
options)
:documentation documentation))
(*protobuf* schema)
The body consists of the enum values in the form 'name' or (name index)."
(let* ((name (or name (class-name->proto type)))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(conc-name (conc-name-for-type type conc-name))
(index -1)
(enum (make-instance 'protobuf-enum
'writer' is a Lisp slot writer function to use to set the value."
(let* ((name (or name (class-name->proto type)))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(conc-name (conc-name-for-type type conc-name))
(message (make-instance 'protobuf-message
:class type
'writer' is a Lisp slot writer function to use to set the value."
(let* ((name (or name (class-name->proto type)))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(message (find-message *protobuf* type))
(conc-name (or (conc-name-for-type type conc-name)
(and message (proto-conc-name message))))
(let* ((slot (or type (and name (proto->slot-name name *protobuf-package*))))
(name (or name (class-name->proto type)))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(conc-name (conc-name-for-type type conc-name))
(reader (or reader
(let ((msg-conc (proto-conc-name *protobuf*)))
(options (append
(loop for (key val) on other-options by #'cddr
unless (member key '(:type :reader :writer :name :default :packed :documentation))
- collect (make-instance 'protobuf-option
- :name (slot-name->proto key)
- :value val))
+ collect (make-option (slot-name->proto key) val))
(loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))))
(multiple-value-bind (ptype pclass)
(clos-type-to-protobuf-type type)
(multiple-value-bind (reqd vectorp)
'input-type' and 'output-type' may also be of the form (type &key name)."
(let* ((name (or name (class-name->proto type)))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(service (make-instance 'protobuf-service
:class type
:name name
(getf (cdr streams-type) :name)))
(streams-type (if (listp streams-type) (car streams-type) streams-type))
(options (loop for (key val) on options by #'cddr
- collect (make-instance 'protobuf-option
- :name (if (symbolp key) (slot-name->proto key) key)
- :value val)))
+ collect (make-option (if (symbolp key) (slot-name->proto key) key) val)))
(package *protobuf-rpc-package*)
(client-fn (intern (format nil "~A-~A" 'call function) package))
(server-fn (intern (format nil "~A-~A" function 'impl) package))
(format stream "~A~@[ = ~S~]" (proto-name o) (proto-value o)))
(format stream "~A" (proto-name o))))
+(defun make-option (name value &optional (type 'string))
+ (check-type name string)
+ (make-instance 'protobuf-option
+ :name key :value val :type type))
+
(defgeneric find-option (protobuf name)
(:documentation
"Given a Protobufs schema, message, enum, etc and the name of an option,
(values (proto-value option) (proto-type option) t)
(values nil nil nil))))
+(defgeneric add-option (protobuf name value &optional type)
+ (:documentation
+ "Given a Protobufs schema, message, enum, etc
+ add the option called 'name' with the value 'value' and type 'type'.
+ If the option was previoously present, it is replaced."))
+
+(defmethod add-option ((protobuf base-protobuf) (name string) value &optional (type 'string))
+ (let ((option (find name (proto-options protobuf) :key #'proto-name :test #'option-name=)))
+ (if option
+ ;; This side-effects the old option
+ (setf (proto-value option) value
+ (proto-type option) type)
+ ;; This side-effects 'proto-options'
+ (setf (proto-options protobuf)
+ (append (proto-options protobuf)
+ (list (make-option key val type)))))))
+
+(defmethod add-option ((options list) (name string) value &optional (type 'string))
+ (let ((option (find name options :key #'proto-name :test #'option-name=)))
+ (setq options (append (remove option options)
+ (list (make-option key val type))))))
+
(defgeneric remove-options (protobuf &rest names)
(:documentation
"Given a Protobufs schema, message, enum, etc and a set of option names,