aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOskari Timperi <oskari.timperi@iki.fi>2018-03-25 14:22:37 +0300
committerOskari Timperi <oskari.timperi@iki.fi>2018-03-25 14:22:37 +0300
commitb447a724437ee1c6bcc27ef6ce05cd700b9d4191 (patch)
tree3ad5328e2602ad7e9d4dc994836091740bbe8f92 /src
parentf26641d78d7ff7a9d19114ec77a9f97378d1f68c (diff)
downloadnimpb-b447a724437ee1c6bcc27ef6ce05cd700b9d4191.tar.gz
nimpb-b447a724437ee1c6bcc27ef6ce05cd700b9d4191.zip
Add initial enum support
Diffstat (limited to 'src')
-rw-r--r--src/protobuf/gen.nim68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/protobuf/gen.nim b/src/protobuf/gen.nim
index 3ef13c2..3e39fa4 100644
--- a/src/protobuf/gen.nim
+++ b/src/protobuf/gen.nim
@@ -21,6 +21,14 @@ type
typeName*: string
packed*: bool
+ EnumDesc* = object
+ name*: string
+ values*: seq[EnumValueDesc]
+
+ EnumValueDesc* = object
+ name*: string
+ number*: int
+
proc findColonExpr(parent: NimNode, s: string): NimNode =
for child in parent:
if child.kind != nnkExprColonExpr:
@@ -54,12 +62,15 @@ proc getFieldType(field: NimNode): FieldType =
proc isMessage(field: NimNode): bool =
result = getFieldType(field) == FieldType.Message
+proc isEnum(field: NimNode): bool =
+ result = getFieldType(field) == FieldType.Enum
+
proc getFieldTypeName(field: NimNode): string =
let node = findColonExpr(field, "typeName")
result = $node[1]
proc getFieldTypeAsString(field: NimNode): string =
- if isMessage(field):
+ if isMessage(field) or isEnum(field):
result = getFieldTypeName(field)
else:
case getFieldType(field)
@@ -112,7 +123,7 @@ proc defaultValue(field: NimNode): NimNode =
of FieldType.Message: result = newCall(ident("new" & getFieldTypeAsString(field)))
of FieldType.Bytes: result = newCall(ident("bytes"), newLit(""))
of FieldType.UInt32: result = newLit(0'u32)
- of FieldType.Enum: result = newLit("TODO")
+ of FieldType.Enum: result = newCall(ident(getFieldTypeAsString(field)), newLit(0))
of FieldType.SFixed32: result = newCall(ident("sfixed32"), newLit(0))
of FieldType.SFixed64: result = newCall(ident("sfixed64"), newLit(0))
of FieldType.SInt32: result = newCall(ident("sint32"), newLit(0))
@@ -452,3 +463,56 @@ macro generateMessageProcs*(x: typed): typed =
when defined(debug):
hint(repr(result))
+
+macro generateEnumType*(x: typed): typed =
+ let
+ impl = getImpl(symbol(x))
+ name = $findColonExpr(impl, "name")[1]
+ values = findColonExpr(impl, "values")[1]
+
+ let enumTy = nnkEnumTy.newTree(newEmptyNode())
+
+ for valueNode in values:
+ let
+ name = $findColonExpr(valueNode, "name")[1]
+ number = findColonExpr(valueNode, "number")[1]
+
+ add(enumTy, nnkEnumFieldDef.newTree(ident(name), number))
+
+ result = newStmtList(nnkTypeSection.newTree(
+ nnkTypeDef.newTree(
+ ident(name),
+ newEmptyNode(),
+ enumTy
+ )
+ ))
+
+ when defined(debug):
+ hint(repr(result))
+
+macro generateEnumProcs*(x: typed): typed =
+ let
+ impl = getImpl(symbol(x))
+ name = $findColonExpr(impl, "name")[1]
+ nameId = ident(name)
+ values = findColonExpr(impl, "values")[1]
+ readProc = postfix(ident("read" & name), "*")
+ writeProc = postfix(ident("write" & name), "*")
+ sizeProc = postfix(ident("sizeOf" & name), "*")
+ resultId = ident("result")
+
+ result = newStmtList()
+
+ add(result, quote do:
+ proc `readProc`(stream: ProtobufStream): `nameId` =
+ `resultId` = `nameId`(readUInt32(stream))
+
+ proc `writeProc`(stream: ProtobufStream, value: `nameId`) =
+ writeEnum(stream, value)
+
+ proc `sizeProc`(value: `nameId`): uint64 =
+ `resultId` = sizeOfUInt32(uint32(value))
+ )
+
+ when defined(debug):
+ hint(repr(result))