planning
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s

This commit is contained in:
2024-10-14 09:15:30 +02:00
parent bcba00a730
commit 6e64e138e2
21059 changed files with 2317811 additions and 1 deletions

7
node_modules/protocol-buffers-schema/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,7 @@
language: node_js
node_js:
- '0.10'
- '0.12'
- '4'
- '5'
- 'node'

21
node_modules/protocol-buffers-schema/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Mathias Buus
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
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

122
node_modules/protocol-buffers-schema/README.md generated vendored Normal file
View File

@@ -0,0 +1,122 @@
# protocol-buffers-schema
No nonsense [protocol buffers](https://developers.google.com/protocol-buffers) schema parser written in Javascript
``` js
npm install protocol-buffers-schema
```
[![build status](http://img.shields.io/travis/mafintosh/protocol-buffers-schema.svg?style=flat)](http://travis-ci.org/mafintosh/protocol-buffers-schema)
## Usage
First save the following file as `example.proto`
```proto
syntax = "proto2";
message Point {
required int32 x = 1;
required int32 y=2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}
```
The run the following example
``` js
var fs = require('fs')
var schema = require('protocol-buffers-schema')
// pass a buffer or string to schema.parse
var sch = schema.parse(fs.readFileSync('example.proto'))
// will print out the schema as a javascript object
console.log(sch)
```
Running the above example will print something like
``` js
{
syntax: 2,
package: null,
enums: [],
messages: [{
name: 'Point',
enums: [],
messages: [],
options: {},
fields: [{
name: 'x',
type: 'int32',
tag: 1,
required: true,
repeated: false,
options: {}
}, {
name: 'y',
type: 'int32',
tag: 2,
required: true,
repeated: false,
options: {}
}, {
name: 'label',
type: 'string',
tag: 3,
required: false,
repeated: false,
options: {}
}]
}, {
name: 'Line',
enums: [],
messages: [],
options: {},
fields: [{
name: 'start',
type: 'Point',
tag: 1,
required: true,
repeated: false,
options: {}
}, {
name: 'end',
type: 'Point',
tag: 2,
required: true,
repeated: false,
options: {}
}, {
name: 'label',
type: 'string',
tag: 3,
required: false,
repeated: false,
options: {}
}]
}],
options:{}
}
```
## API
#### `schema.parse(protobufSchemaBufferOrString)`
Parses a .proto schema into a javascript object
#### `schema.stringify(schema)`
Stringifies a parsed schema back into .proto format
## License
MIT

11
node_modules/protocol-buffers-schema/example.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
var schema = require('./')
var fs = require('fs')
var sch = schema.parse(fs.readFileSync('example.proto'))
console.log('Parsed schema:')
console.log(JSON.stringify(sch, null, 2))
console.log('')
console.log('Stringified schema:')
console.log(schema.stringify(sch))

13
node_modules/protocol-buffers-schema/example.proto generated vendored Normal file
View File

@@ -0,0 +1,13 @@
// example file
message Test {
map<string, string> data = 1;
required string hello = 2;
oneof test {
uint32 age = 3;
uint32 year = 4;
}
message Nested {
optional bytes thing = 1;
}
}

6
node_modules/protocol-buffers-schema/index.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
var parse = require('./parse')
var stringify = require('./stringify')
module.exports = parse
module.exports.parse = parse
module.exports.stringify = stringify

31
node_modules/protocol-buffers-schema/package.json generated vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"name": "protocol-buffers-schema",
"version": "3.6.0",
"description": "No nonsense protocol buffers schema parser written in Javascript",
"main": "index.js",
"devDependencies": {
"standard": "^10.0.3",
"tape": "^4.8.0"
},
"scripts": {
"test": "standard && tape test/*.js"
},
"repository": {
"type": "git",
"url": "https://github.com/mafintosh/protocol-buffers-schema"
},
"keywords": [
"protobuf",
"protocol",
"buffers",
"schema",
"parser",
"parse"
],
"author": "Mathias Buus",
"license": "MIT",
"bugs": {
"url": "https://github.com/mafintosh/protocol-buffers-schema/issues"
},
"homepage": "https://github.com/mafintosh/protocol-buffers-schema"
}

769
node_modules/protocol-buffers-schema/parse.js generated vendored Normal file
View File

@@ -0,0 +1,769 @@
var tokenize = require('./tokenize')
var MAX_RANGE = 0x1FFFFFFF
// "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire types) can be declared "packed"."
// https://developers.google.com/protocol-buffers/docs/encoding#optional
var PACKABLE_TYPES = [
// varint wire types
'int32', 'int64', 'uint32', 'uint64', 'sint32', 'sint64', 'bool',
// + ENUMS
// 64-bit wire types
'fixed64', 'sfixed64', 'double',
// 32-bit wire types
'fixed32', 'sfixed32', 'float'
]
var onfieldoptionvalue = function (tokens) {
var value = tokens.shift()
if (value !== '{') {
return value
}
value = {}
var field = ''
while (tokens.length) {
switch (tokens[0]) {
case '}':
tokens.shift()
return value
case ':':
tokens.shift()
value[field] = onfieldoptionvalue(tokens)
break
default:
field = tokens.shift()
}
}
}
var onfieldoptions = function (tokens) {
var opts = {}
while (tokens.length) {
switch (tokens[0]) {
case '[':
case ',': {
tokens.shift()
var name = tokens.shift()
if (name === '(') { // handling [(A) = B]
name = tokens.shift()
tokens.shift() // remove the end of bracket
}
var field = []
if (tokens[0][0] === '.') {
field = tokens[0].substr(1).split('.')
tokens.shift()
}
if (tokens[0] !== '=') throw new Error('Unexpected token in field options: ' + tokens[0])
tokens.shift()
if (tokens[0] === ']') throw new Error('Unexpected ] in field option')
// for option (A).b.c
// path will be ['A', 'b'] and lastFieldName 'c'
var path = [name].concat(field)
var lastFieldName = path.pop()
// opt references opts.A.b
var opt = path.reduce(function (opt, n, index) {
if (opt[n] == null) {
opt[n] = {}
}
return opt[n]
}, opts)
// now set opt['c'] that references opts.A.b['c']
opt[lastFieldName] = onfieldoptionvalue(tokens)
break
}
case ']':
tokens.shift()
return opts
default:
throw new Error('Unexpected token in field options: ' + tokens[0])
}
}
throw new Error('No closing tag for field options')
}
var onfield = function (tokens) {
var field = {
name: null,
type: null,
tag: -1,
map: null,
oneof: null,
required: false,
repeated: false,
options: {}
}
while (tokens.length) {
switch (tokens[0]) {
case '=':
tokens.shift()
field.tag = Number(tokens.shift())
break
case 'map':
field.type = 'map'
field.map = { from: null, to: null }
tokens.shift()
if (tokens[0] !== '<') throw new Error('Unexpected token in map type: ' + tokens[0])
tokens.shift()
field.map.from = tokens.shift()
if (tokens[0] !== ',') throw new Error('Unexpected token in map type: ' + tokens[0])
tokens.shift()
field.map.to = tokens.shift()
if (tokens[0] !== '>') throw new Error('Unexpected token in map type: ' + tokens[0])
tokens.shift()
field.name = tokens.shift()
break
case 'repeated':
case 'required':
case 'optional':
var t = tokens.shift()
field.required = t === 'required'
field.repeated = t === 'repeated'
field.type = tokens.shift()
field.name = tokens.shift()
break
case '[':
field.options = onfieldoptions(tokens)
break
case ';':
if (field.name === null) throw new Error('Missing field name')
if (field.type === null) throw new Error('Missing type in message field: ' + field.name)
if (field.tag === -1) throw new Error('Missing tag number in message field: ' + field.name)
tokens.shift()
return field
default:
throw new Error('Unexpected token in message field: ' + tokens[0])
}
}
throw new Error('No ; found for message field')
}
var onmessagebody = function (tokens) {
var body = {
enums: [],
options: {},
messages: [],
fields: [],
extends: [],
extensions: null
}
while (tokens.length) {
switch (tokens[0]) {
case 'map':
case 'repeated':
case 'optional':
case 'required':
body.fields.push(onfield(tokens))
break
case 'enum':
body.enums.push(onenum(tokens))
break
case 'message':
body.messages.push(onmessage(tokens))
break
case 'extensions':
body.extensions = onextensions(tokens)
break
case 'oneof':
tokens.shift()
var name = tokens.shift()
if (tokens[0] !== '{') throw new Error('Unexpected token in oneof: ' + tokens[0])
tokens.shift()
while (tokens[0] !== '}') {
tokens.unshift('optional')
var field = onfield(tokens)
field.oneof = name
body.fields.push(field)
}
tokens.shift()
break
case 'extend':
body.extends.push(onextend(tokens))
break
case ';':
tokens.shift()
break
case 'reserved':
tokens.shift()
while (tokens[0] !== ';') {
tokens.shift()
}
break
case 'option':
var opt = onoption(tokens)
if (body.options[opt.name] !== undefined) throw new Error('Duplicate option ' + opt.name)
body.options[opt.name] = opt.value
break
default:
// proto3 does not require the use of optional/required, assumed as optional
// "singular: a well-formed message can have zero or one of this field (but not more than one)."
// https://developers.google.com/protocol-buffers/docs/proto3#specifying-field-rules
tokens.unshift('optional')
body.fields.push(onfield(tokens))
}
}
return body
}
var onextend = function (tokens) {
var out = {
name: tokens[1],
message: onmessage(tokens)
}
return out
}
var onextensions = function (tokens) {
tokens.shift()
var from = Number(tokens.shift())
if (isNaN(from)) throw new Error('Invalid from in extensions definition')
if (tokens.shift() !== 'to') throw new Error("Expected keyword 'to' in extensions definition")
var to = tokens.shift()
if (to === 'max') to = MAX_RANGE
to = Number(to)
if (isNaN(to)) throw new Error('Invalid to in extensions definition')
if (tokens.shift() !== ';') throw new Error('Missing ; in extensions definition')
return { from: from, to: to }
}
var onmessage = function (tokens) {
tokens.shift()
var lvl = 1
var body = []
var msg = {
name: tokens.shift(),
options: {},
enums: [],
extends: [],
messages: [],
fields: []
}
if (tokens[0] !== '{') throw new Error('Expected { but found ' + tokens[0])
tokens.shift()
while (tokens.length) {
if (tokens[0] === '{') lvl++
else if (tokens[0] === '}') lvl--
if (!lvl) {
tokens.shift()
body = onmessagebody(body)
msg.enums = body.enums
msg.messages = body.messages
msg.fields = body.fields
msg.extends = body.extends
msg.extensions = body.extensions
msg.options = body.options
return msg
}
body.push(tokens.shift())
}
if (lvl) throw new Error('No closing tag for message')
}
var onpackagename = function (tokens) {
tokens.shift()
var name = tokens.shift()
if (tokens[0] !== ';') throw new Error('Expected ; but found ' + tokens[0])
tokens.shift()
return name
}
var onsyntaxversion = function (tokens) {
tokens.shift()
if (tokens[0] !== '=') throw new Error('Expected = but found ' + tokens[0])
tokens.shift()
var version = tokens.shift()
switch (version) {
case '"proto2"':
version = 2
break
case '"proto3"':
version = 3
break
default:
throw new Error('Expected protobuf syntax version but found ' + version)
}
if (tokens[0] !== ';') throw new Error('Expected ; but found ' + tokens[0])
tokens.shift()
return version
}
var onenumvalue = function (tokens) {
if (tokens.length < 4) throw new Error('Invalid enum value: ' + tokens.slice(0, 3).join(' '))
if (tokens[0] === 'reserved') {
tokens.shift()
while (tokens[0] !== ';') {
tokens.shift()
}
tokens.shift()
return null
}
if (tokens[1] !== '=') throw new Error('Expected = but found ' + tokens[1])
if (tokens[3] !== ';' && tokens[3] !== '[') throw new Error('Expected ; or [ but found ' + tokens[1])
var name = tokens.shift()
tokens.shift()
var val = {
value: null,
options: {}
}
val.value = Number(tokens.shift())
if (tokens[0] === '[') {
val.options = onfieldoptions(tokens)
}
tokens.shift() // expecting the semicolon here
return {
name: name,
val: val
}
}
var onenum = function (tokens) {
tokens.shift()
var options = {}
var e = {
name: tokens.shift(),
values: {},
options: {}
}
if (tokens[0] !== '{') throw new Error('Expected { but found ' + tokens[0])
tokens.shift()
while (tokens.length) {
if (tokens[0] === '}') {
tokens.shift()
// there goes optional semicolon after the enclosing "}"
if (tokens[0] === ';') tokens.shift()
return e
}
if (tokens[0] === 'option') {
options = onoption(tokens)
e.options[options.name] = options.value
continue
}
var val = onenumvalue(tokens)
if (val !== null) {
e.values[val.name] = val.val
}
}
throw new Error('No closing tag for enum')
}
var onoption = function (tokens) {
var name = null
var value = null
var parse = function (value) {
if (value === 'true') return true
if (value === 'false') return false
return value.replace(/^"+|"+$/gm, '')
}
while (tokens.length) {
if (tokens[0] === ';') {
tokens.shift()
return { name: name, value: value }
}
switch (tokens[0]) {
case 'option':
tokens.shift()
var hasBracket = tokens[0] === '('
if (hasBracket) tokens.shift()
name = tokens.shift()
if (hasBracket) {
if (tokens[0] !== ')') throw new Error('Expected ) but found ' + tokens[0])
tokens.shift()
}
if (tokens[0][0] === '.') {
name += tokens.shift()
}
break
case '=':
tokens.shift()
if (name === null) throw new Error('Expected key for option with value: ' + tokens[0])
value = parse(tokens.shift())
if (name === 'optimize_for' && !/^(SPEED|CODE_SIZE|LITE_RUNTIME)$/.test(value)) {
throw new Error('Unexpected value for option optimize_for: ' + value)
} else if (value === '{') {
// option foo = {bar: baz}
value = onoptionMap(tokens)
}
break
default:
throw new Error('Unexpected token in option: ' + tokens[0])
}
}
}
var onoptionMap = function (tokens) {
var parse = function (value) {
if (value === 'true') return true
if (value === 'false') return false
return value.replace(/^"+|"+$/gm, '')
}
var map = {}
while (tokens.length) {
if (tokens[0] === '}') {
tokens.shift()
return map
}
var hasBracket = tokens[0] === '('
if (hasBracket) tokens.shift()
var key = tokens.shift()
if (hasBracket) {
if (tokens[0] !== ')') throw new Error('Expected ) but found ' + tokens[0])
tokens.shift()
}
var value = null
switch (tokens[0]) {
case ':':
if (map[key] !== undefined) throw new Error('Duplicate option map key ' + key)
tokens.shift()
value = parse(tokens.shift())
if (value === '{') {
// option foo = {bar: baz}
value = onoptionMap(tokens)
}
map[key] = value
if (tokens[0] === ';') {
tokens.shift()
}
break
case '{':
tokens.shift()
value = onoptionMap(tokens)
if (map[key] === undefined) map[key] = []
if (!Array.isArray(map[key])) throw new Error('Duplicate option map key ' + key)
map[key].push(value)
break
default:
throw new Error('Unexpected token in option map: ' + tokens[0])
}
}
throw new Error('No closing tag for option map')
}
var onimport = function (tokens) {
tokens.shift()
var file = tokens.shift().replace(/^"+|"+$/gm, '')
if (tokens[0] !== ';') throw new Error('Unexpected token: ' + tokens[0] + '. Expected ";"')
tokens.shift()
return file
}
var onservice = function (tokens) {
tokens.shift()
var service = {
name: tokens.shift(),
methods: [],
options: {}
}
if (tokens[0] !== '{') throw new Error('Expected { but found ' + tokens[0])
tokens.shift()
while (tokens.length) {
if (tokens[0] === '}') {
tokens.shift()
// there goes optional semicolon after the enclosing "}"
if (tokens[0] === ';') tokens.shift()
return service
}
switch (tokens[0]) {
case 'option':
var opt = onoption(tokens)
if (service.options[opt.name] !== undefined) throw new Error('Duplicate option ' + opt.name)
service.options[opt.name] = opt.value
break
case 'rpc':
service.methods.push(onrpc(tokens))
break
default:
throw new Error('Unexpected token in service: ' + tokens[0])
}
}
throw new Error('No closing tag for service')
}
var onrpc = function (tokens) {
tokens.shift()
var rpc = {
name: tokens.shift(),
input_type: null,
output_type: null,
client_streaming: false,
server_streaming: false,
options: {}
}
if (tokens[0] !== '(') throw new Error('Expected ( but found ' + tokens[0])
tokens.shift()
if (tokens[0] === 'stream') {
tokens.shift()
rpc.client_streaming = true
}
rpc.input_type = tokens.shift()
if (tokens[0] !== ')') throw new Error('Expected ) but found ' + tokens[0])
tokens.shift()
if (tokens[0] !== 'returns') throw new Error('Expected returns but found ' + tokens[0])
tokens.shift()
if (tokens[0] !== '(') throw new Error('Expected ( but found ' + tokens[0])
tokens.shift()
if (tokens[0] === 'stream') {
tokens.shift()
rpc.server_streaming = true
}
rpc.output_type = tokens.shift()
if (tokens[0] !== ')') throw new Error('Expected ) but found ' + tokens[0])
tokens.shift()
if (tokens[0] === ';') {
tokens.shift()
return rpc
}
if (tokens[0] !== '{') throw new Error('Expected { but found ' + tokens[0])
tokens.shift()
while (tokens.length) {
if (tokens[0] === '}') {
tokens.shift()
// there goes optional semicolon after the enclosing "}"
if (tokens[0] === ';') tokens.shift()
return rpc
}
if (tokens[0] === 'option') {
var opt = onoption(tokens)
if (rpc.options[opt.name] !== undefined) throw new Error('Duplicate option ' + opt.name)
rpc.options[opt.name] = opt.value
} else {
throw new Error('Unexpected token in rpc options: ' + tokens[0])
}
}
throw new Error('No closing tag for rpc')
}
var parse = function (buf) {
var tokens = tokenize(buf.toString())
// check for isolated strings in tokens by looking for opening quote
for (var i = 0; i < tokens.length; i++) {
if (/^("|')([^'"]*)$/.test(tokens[i])) {
var j
if (tokens[i].length === 1) {
j = i + 1
} else {
j = i
}
// look ahead for the closing quote and collapse all
// in-between tokens into a single token
for (j; j < tokens.length; j++) {
if (/^[^'"\\]*(?:\\.[^'"\\]*)*("|')$/.test(tokens[j])) {
tokens = tokens.slice(0, i).concat(tokens.slice(i, j + 1).join('')).concat(tokens.slice(j + 1))
break
}
}
}
}
var schema = {
syntax: 3,
package: null,
imports: [],
enums: [],
messages: [],
options: {},
extends: []
}
var firstline = true
while (tokens.length) {
switch (tokens[0]) {
case 'package':
schema.package = onpackagename(tokens)
break
case 'syntax':
if (!firstline) throw new Error('Protobuf syntax version should be first thing in file')
schema.syntax = onsyntaxversion(tokens)
break
case 'message':
schema.messages.push(onmessage(tokens))
break
case 'enum':
schema.enums.push(onenum(tokens))
break
case 'option':
var opt = onoption(tokens)
if (schema.options[opt.name]) throw new Error('Duplicate option ' + opt.name)
schema.options[opt.name] = opt.value
break
case 'import':
schema.imports.push(onimport(tokens))
break
case 'extend':
schema.extends.push(onextend(tokens))
break
case 'service':
if (!schema.services) schema.services = []
schema.services.push(onservice(tokens))
break
default:
throw new Error('Unexpected token: ' + tokens[0])
}
firstline = false
}
// now iterate over messages and propagate extends
schema.extends.forEach(function (ext) {
schema.messages.forEach(function (msg) {
if (msg.name === ext.name) {
ext.message.fields.forEach(function (field) {
if (!msg.extensions || field.tag < msg.extensions.from || field.tag > msg.extensions.to) {
throw new Error(msg.name + ' does not declare ' + field.tag + ' as an extension number')
}
msg.fields.push(field)
})
}
})
})
schema.messages.forEach(function (msg) {
msg.fields.forEach(function (field) {
var fieldSplit
var messageName
var nestedEnumName
var message
function enumNameIsFieldType (en) {
return en.name === field.type
}
function enumNameIsNestedEnumName (en) {
return en.name === nestedEnumName
}
if (field.options && field.options.packed === 'true') {
if (PACKABLE_TYPES.indexOf(field.type) === -1) {
// let's see if it's an enum
if (field.type.indexOf('.') === -1) {
if (msg.enums && msg.enums.some(enumNameIsFieldType)) {
return
}
} else {
fieldSplit = field.type.split('.')
if (fieldSplit.length > 2) {
throw new Error('what is this?')
}
messageName = fieldSplit[0]
nestedEnumName = fieldSplit[1]
schema.messages.some(function (msg) {
if (msg.name === messageName) {
message = msg
return msg
}
})
if (message && message.enums && message.enums.some(enumNameIsNestedEnumName)) {
return
}
}
throw new Error(
'Fields of type ' + field.type + ' cannot be declared [packed=true]. ' +
'Only repeated fields of primitive numeric types (types which use ' +
'the varint, 32-bit, or 64-bit wire types) can be declared "packed". ' +
'See https://developers.google.com/protocol-buffers/docs/encoding#optional'
)
}
}
})
})
return schema
}
module.exports = parse

206
node_modules/protocol-buffers-schema/stringify.js generated vendored Normal file
View File

@@ -0,0 +1,206 @@
var onimport = function (i, result) {
result.push('import "' + i + '";', '')
return result
}
var onfield = function (f, result) {
var prefix = f.repeated ? 'repeated' : f.required ? 'required' : 'optional'
if (f.type === 'map') prefix = 'map<' + f.map.from + ',' + f.map.to + '>'
if (f.oneof) prefix = ''
var opts = Object.keys(f.options || {}).map(function (key) {
return key + ' = ' + f.options[key]
}).join(',')
if (opts) opts = ' [' + opts + ']'
result.push((prefix ? prefix + ' ' : '') + (f.map === 'map' ? '' : f.type + ' ') + f.name + ' = ' + f.tag + opts + ';')
return result
}
var onmessage = function (m, result) {
result.push('message ' + m.name + ' {')
if (!m.options) m.options = {}
onoption(m.options, result)
if (!m.enums) m.enums = []
m.enums.forEach(function (e) {
result.push(onenum(e, []))
})
if (!m.messages) m.messages = []
m.messages.forEach(function (m) {
result.push(onmessage(m, []))
})
var oneofs = {}
if (!m.fields) m.fields = []
m.fields.forEach(function (f) {
if (f.oneof) {
if (!oneofs[f.oneof]) oneofs[f.oneof] = []
oneofs[f.oneof].push(onfield(f, []))
} else {
result.push(onfield(f, []))
}
})
Object.keys(oneofs).forEach(function (n) {
oneofs[n].unshift('oneof ' + n + ' {')
oneofs[n].push('}')
result.push(oneofs[n])
})
result.push('}', '')
return result
}
var onenum = function (e, result) {
result.push('enum ' + e.name + ' {')
if (!e.options) e.options = {}
var options = onoption(e.options, [])
if (options.length > 1) {
result.push(options.slice(0, -1))
}
Object.keys(e.values).map(function (v) {
var val = onenumvalue(e.values[v])
result.push([v + ' = ' + val + ';'])
})
result.push('}', '')
return result
}
var onenumvalue = function (v, result) {
var opts = Object.keys(v.options || {}).map(function (key) {
return key + ' = ' + v.options[key]
}).join(',')
if (opts) opts = ' [' + opts + ']'
var val = v.value + opts
return val
}
var onoption = function (o, result) {
var keys = Object.keys(o)
keys.forEach(function (option) {
var v = o[option]
if (~option.indexOf('.')) option = '(' + option + ')'
var type = typeof v
if (type === 'object') {
v = onoptionMap(v, [])
if (v.length) result.push('option ' + option + ' = {', v, '};')
} else {
if (type === 'string' && option !== 'optimize_for') v = '"' + v + '"'
result.push('option ' + option + ' = ' + v + ';')
}
})
if (keys.length > 0) {
result.push('')
}
return result
}
var onoptionMap = function (o, result) {
var keys = Object.keys(o)
keys.forEach(function (k) {
var v = o[k]
var type = typeof v
if (type === 'object') {
if (Array.isArray(v)) {
v.forEach(function (v) {
v = onoptionMap(v, [])
if (v.length) result.push(k + ' {', v, '}')
})
} else {
v = onoptionMap(v, [])
if (v.length) result.push(k + ' {', v, '}')
}
} else {
if (type === 'string') v = '"' + v + '"'
result.push(k + ': ' + v)
}
})
return result
}
var onservices = function (s, result) {
result.push('service ' + s.name + ' {')
if (!s.options) s.options = {}
onoption(s.options, result)
if (!s.methods) s.methods = []
s.methods.forEach(function (m) {
result.push(onrpc(m, []))
})
result.push('}', '')
return result
}
var onrpc = function (rpc, result) {
var def = 'rpc ' + rpc.name + '('
if (rpc.client_streaming) def += 'stream '
def += rpc.input_type + ') returns ('
if (rpc.server_streaming) def += 'stream '
def += rpc.output_type + ')'
if (!rpc.options) rpc.options = {}
var options = onoption(rpc.options, [])
if (options.length > 1) {
result.push(def + ' {', options.slice(0, -1), '}')
} else {
result.push(def + ';')
}
return result
}
var indent = function (lvl) {
return function (line) {
if (Array.isArray(line)) return line.map(indent(lvl + ' ')).join('\n')
return lvl + line
}
}
module.exports = function (schema) {
var result = []
result.push('syntax = "proto' + schema.syntax + '";', '')
if (schema.package) result.push('package ' + schema.package + ';', '')
if (schema.imports) {
schema.imports.forEach(function (i) {
onimport(i, result)
})
}
if (!schema.options) schema.options = {}
onoption(schema.options, result)
if (!schema.enums) schema.enums = []
schema.enums.forEach(function (e) {
onenum(e, result)
})
if (!schema.messages) schema.messages = []
schema.messages.forEach(function (m) {
onmessage(m, result)
})
if (schema.services) {
schema.services.forEach(function (s) {
onservices(s, result)
})
}
return result.map(indent('')).join('\n')
}

View File

@@ -0,0 +1,90 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"extends": [],
"messages": [
{
"name": "Point",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"extensions": null,
"fields": [
{
"name": "x",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "y",
"type": "int32",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
},
{
"name": "Line",
"enums": [],
"extends": [],
"extensions": null,
"messages": [],
"options": {},
"fields": [
{
"name": "start",
"type": "Point",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "end",
"type": "Point",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
}
],
"options":{}
}

View File

@@ -0,0 +1,11 @@
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}

View File

@@ -0,0 +1,99 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"extends": [],
"messages": [
{
"name": "Point",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"extensions": null,
"fields": [
{
"name": "x",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "y",
"type": "int32",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
},
{
"name": "Line",
"enums": [],
"extends": [],
"options": {},
"extensions": null,
"messages": [],
"fields": [
{
"name": "start",
"type": "Point",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "end",
"type": "Point",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
},
{
"name": "A",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [],
"extensions": null
}
],
"options":{}
}

View File

@@ -0,0 +1,19 @@
//Single-line comment
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
/*Multi-line comment*/
message Line {/*
*/required Point start = 1;
required Point end = 2;
optional string label = 3;
}
/**
* Doxygen-style comment
**/
message A {
}//Comment after closing brace of last message

View File

@@ -0,0 +1,125 @@
{
"syntax": 3,
"package": "tutorial",
"imports": [],
"enums": [],
"messages": [{
"name": "Person",
"options": {},
"enums": [{
"name": "PhoneType",
"values": {
"MOBILE": {
"value": 0,
"options": {
"some_enum_option": "true"
}
},
"HOME": {
"value": 1,
"options": {}
},
"WORK": {
"value": 2,
"options": {}
}
},
"options": {
"allow_alias": true,
"custom_option": true
}
}],
"extends": [],
"messages": [{
"name": "PhoneNumber",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [{
"name": "number",
"type": "string",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
}, {
"name": "type",
"type": "PhoneType",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"default": "HOME"
}
}],
"extensions": null
}],
"fields": [{
"name": "name",
"type": "string",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
}, {
"name": "id",
"type": "int32",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
}, {
"name": "email",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}, {
"name": "phone",
"type": "PhoneNumber",
"tag": 4,
"map": null,
"oneof": null,
"required": false,
"repeated": true,
"options": {}
}],
"extensions": null
}, {
"name": "AddressBook",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [{
"name": "person",
"type": "Person",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": true,
"options": {}
}],
"extensions": null
}],
"options": {
"java_package": "com.mafintosh.generated",
"java_outer_classname": "Example",
"java_generate_equals_and_hash": true,
"optimize_for": "SPEED"
},
"extends": []
}

View File

@@ -0,0 +1,30 @@
package tutorial;
option java_package = "com.mafintosh.generated";
option java_outer_classname = "Example";
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;
message Person {
enum PhoneType {
option allow_alias = true;
option custom_option = true;
MOBILE = 0 [some_enum_option = true];
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
required string name = 1;
required int32 id = 2;
optional string email = 3;
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}

View File

@@ -0,0 +1,42 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [{
"name": "Person",
"enums": [{
"name": "PhoneType",
"values": {
"MOBILE": {
"value": 0,
"options": {
"enum_value_is_deprecated": "true",
"some_second_option": "\"value1, value2, value3\"",
"some_third_option": "'[value1, value2, value3]'"
}
},
"HOME": {
"value": 1,
"options": {
"enum_value_is_deprecated": "true"
}
},
"WORK": {
"value": 2,
"options": {}
}
},
"options": {
"allow_alias": true
}
}],
"extends": [],
"messages": [],
"options": {},
"fields": [],
"extensions": null
}],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,8 @@
message Person {
enum PhoneType {
option allow_alias = true;
MOBILE = 0 [(enum_value_is_deprecated) = true, (some_second_option) = "value1, value2, value3", (some_third_option) = '[value1, value2, value3]'];
HOME = 1 [(enum_value_is_deprecated) = true];
WORK = 2;
}
}

View File

@@ -0,0 +1,32 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [
{
"name": "Event",
"enums": [],
"options": {},
"extends": [],
"messages": [],
"fields": [
{
"name": "id",
"type": "EntityId",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"tagger.tags": "\"a:'Hello, there', bson:\\\"_id,omitempty\\\"\""
}
}
],
"extensions": null
}
],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,3 @@
message Event {
EntityId id = 1 [(tagger.tags) = "a:'Hello, there', bson:\"_id,omitempty\"" ];
}

View File

@@ -0,0 +1,167 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [
{
"name": "MsgNormal",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "field1",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "field2",
"type": "string",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "field3",
"type": "int32",
"tag": 3,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "exField1",
"type": "int32",
"tag": 101,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "exField2",
"type": "string",
"tag": 102,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
},
{
"name": "MsgExtend",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "field1",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "field2",
"type": "string",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "field3",
"type": "int32",
"tag": 3,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "exField1",
"type": "int32",
"tag": 101,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "exField2",
"type": "string",
"tag": 102,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": {
"from": 100,
"to": 200
}
}
],
"options": {},
"extends": [
{
"name": "MsgExtend",
"message": {
"name": "MsgExtend",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "exField1",
"type": "int32",
"tag": 101,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "exField2",
"type": "string",
"tag": 102,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
}
]
}

View File

@@ -0,0 +1,19 @@
message MsgNormal {
required int32 field1 = 1;
optional string field2 = 2;
required int32 field3 = 3;
optional int32 exField1 = 101;
optional string exField2 = 102;
}
message MsgExtend {
required int32 field1 = 1;
optional string field2 = 2;
required int32 field3 = 3;
extensions 100 to 200;
}
extend MsgExtend {
optional int32 exField1 = 101;
optional string exField2 = 102;
}

View File

@@ -0,0 +1,30 @@
{
"syntax": 3,
"package": null,
"imports": ["./result.proto", "./other_result.proto"],
"enums": [],
"extends": [],
"messages": [
{
"name": "SearchResponse",
"extensions": null,
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "result",
"type": "Result",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": true,
"options": {}
}
]
}
],
"options": {}
}

View File

@@ -0,0 +1,6 @@
import "./result.proto";
import "./other_result.proto";
message SearchResponse {
repeated Result result = 1;
}

View File

@@ -0,0 +1,33 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [
{
"name": "Data",
"enums": [],
"options": {},
"extends": [],
"messages": [],
"fields": [
{
"name": "data",
"type": "map",
"map": {
"from": "string",
"to": "bytes"
},
"oneof": null,
"tag": 1,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,3 @@
message Data {
map<string,bytes> data = 1;
}

View File

@@ -0,0 +1,8 @@
message wallet {
optional int32 dollars;
optional int32 pesos;
}
message traveller {
required wallet wallet;
}

View File

@@ -0,0 +1,41 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [
{
"name": "SampleMessage",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "name",
"type": "string",
"tag": 4,
"map": null,
"oneof": "test_oneof",
"required": false,
"repeated": false,
"options": {}
},
{
"name": "sub_message",
"type": "SubMessage",
"tag": 9,
"map": null,
"oneof": "test_oneof",
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,6 @@
message SampleMessage {
oneof test_oneof {
string name = 4;
SubMessage sub_message = 9;
}
}

View File

@@ -0,0 +1,364 @@
{
"syntax": 3,
"package": null,
"imports": [
"google/protobuf/descriptor.proto"
],
"enums": [
{
"name": "MyEnum",
"values": {
"FOO": {
"value": 1,
"options": {
"my_enum_value_option": "321"
}
},
"BAR": {
"value": 2,
"options": {}
}
},
"options": {
"my_enum_option": true
}
}
],
"messages": [
{
"name": "MyMessage",
"enums": [],
"extends": [],
"messages": [],
"options": {
"my_message_option": "1234"
},
"fields": [
{
"name": "foo",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"my_field_option": "4.5"
}
},
{
"name": "bar",
"type": "string",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
},
{
"name": "RequestType",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [],
"extensions": null
},
{
"name": "ResponseType",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [],
"extensions": null
},
{
"name": "FooOptions",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "opt1",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "opt2",
"type": "string",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
},
{
"name": "Bar",
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "a",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"foo_options": {
"opt1": "123",
"opt2": "\"baz\""
}
}
},
{
"name": "b",
"type": "int32",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"foo_options": {
"opt1": "123",
"opt2": "\"baz\""
}
}
}
],
"extensions": null
}
],
"options": {
"my_file_option": "Hello world!"
},
"extends": [
{
"name": "google.protobuf.FileOptions",
"message": {
"name": "google.protobuf.FileOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_file_option",
"type": "string",
"tag": 50000,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.MessageOptions",
"message": {
"name": "google.protobuf.MessageOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_message_option",
"type": "int32",
"tag": 50001,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.FieldOptions",
"message": {
"name": "google.protobuf.FieldOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_field_option",
"type": "float",
"tag": 50002,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.EnumOptions",
"message": {
"name": "google.protobuf.EnumOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_enum_option",
"type": "bool",
"tag": 50003,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.EnumValueOptions",
"message": {
"name": "google.protobuf.EnumValueOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_enum_value_option",
"type": "uint32",
"tag": 50004,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.ServiceOptions",
"message": {
"name": "google.protobuf.ServiceOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_service_option",
"type": "MyEnum",
"tag": 50005,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.MethodOptions",
"message": {
"name": "google.protobuf.MethodOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "my_method_option",
"type": "MyMessage",
"tag": 50006,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
},
{
"name": "google.protobuf.FieldOptions",
"message": {
"name": "google.protobuf.FieldOptions",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "foo_options",
"type": "FooOptions",
"tag": 1234,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
],
"extensions": null
}
}
],
"services": [
{
"name": "MyService",
"methods": [
{
"name": "MyMethod",
"input_type": "RequestType",
"output_type": "ResponseType",
"client_streaming": false,
"server_streaming": false,
"options": {
"my_method_option.foo": "567",
"my_method_option.bar": "Some string"
}
}
],
"options": {
"my_service_option": "FOO",
"my_service_option_map": {
"foo": "bar"
}
}
}
]
}

View File

@@ -0,0 +1,72 @@
import "google/protobuf/descriptor.proto";
extend google.protobuf.FileOptions {
optional string my_file_option = 50000;
}
extend google.protobuf.MessageOptions {
optional int32 my_message_option = 50001;
}
extend google.protobuf.FieldOptions {
optional float my_field_option = 50002;
}
extend google.protobuf.EnumOptions {
optional bool my_enum_option = 50003;
}
extend google.protobuf.EnumValueOptions {
optional uint32 my_enum_value_option = 50004;
}
extend google.protobuf.ServiceOptions {
optional MyEnum my_service_option = 50005;
}
extend google.protobuf.MethodOptions {
optional MyMessage my_method_option = 50006;
}
option (my_file_option) = "Hello world!";
message MyMessage {
option (my_message_option) = 1234;
optional int32 foo = 1 [(my_field_option) = 4.5];
optional string bar = 2;
}
enum MyEnum {
option (my_enum_option) = true;
FOO = 1 [(my_enum_value_option) = 321];
BAR = 2;
}
message RequestType {}
message ResponseType {}
service MyService {
option (my_service_option) = FOO;
option (my_service_option_map) = {
foo: "bar";
};
rpc MyMethod(RequestType) returns(ResponseType) {
// Note: my_method_option has type MyMessage. We can set each field
// within it using a separate "option" line.
option (my_method_option).foo = 567;
option (my_method_option).bar = "Some string";
}
}
message FooOptions {
optional int32 opt1 = 1;
optional string opt2 = 2;
}
extend google.protobuf.FieldOptions {
optional FooOptions foo_options = 1234;
}
// usage:
message Bar {
optional int32 a = 1 [(foo_options).opt1 = 123, (foo_options).opt2 = "baz"];
// alternative aggregate syntax (uses TextFormat):
optional int32 b = 2 [(foo_options) = { opt1: 123 opt2: "baz" }];
}

View File

@@ -0,0 +1,47 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"messages": [{
"name": "OptionFields",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [{
"name": "type",
"type": "string",
"tag": 2,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"mylist": "\"some,values,[here]\""
}
}],
"extensions": null
}, {
"name": "MoreOptionFields",
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [{
"name": "values",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {
"mylist2": "'[more, values], [here]'"
}
}],
"extensions": null
}],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,8 @@
message OptionFields {
optional string type = 2 [mylist = "some,values,[here]"];
}
message MoreOptionFields {
optional string values = 3 [mylist2 = '[more, values], [here]'];
}

View File

@@ -0,0 +1,8 @@
message deviceTrajectory {
required bytes dates = 1 [packed=true];
required bytes signal_strengths = 2 [packed=true];
}
message trajectories {
repeated deviceTrajectory trajectories = 1 [packed=true];
}

View File

@@ -0,0 +1,55 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [
{
"name": "ReservedEnum",
"values": {
"x": {
"value": 1,
"options": []
},
"y": {
"value": 10,
"options": []
}
},
"options": {}
}
],
"messages": [
{
"name": "Reserved",
"extensions": null,
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "x",
"type": "string",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
},
{
"name": "y",
"type": "string",
"tag": 10,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
}
],
"options": {},
"extends": []
}

View File

@@ -0,0 +1,17 @@
syntax = "proto3";
message Reserved {
string x = 1;
reserved 2, 3;
reserved 5 to 9;
reserved "foo", "bar";
string y = 10;
}
enum ReservedEnum {
x = 1;
reserved 2, 3;
reserved 5 to 9;
reserved "foo", "bar";
y = 10;
}

View File

@@ -0,0 +1,30 @@
{
"syntax": 3,
"package": null,
"imports": ["./result.proto"],
"enums": [],
"extends": [],
"messages": [
{
"name": "SearchResponse",
"extensions": null,
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "result",
"type": "Result",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": true,
"options": {}
}
]
}
],
"options":{}
}

View File

@@ -0,0 +1,5 @@
import "./result.proto";
message SearchResponse {
repeated Result result = 1;
}

View File

@@ -0,0 +1,108 @@
{
"syntax": 3,
"package": null,
"imports": [],
"enums": [],
"extends": [],
"messages": [
{
"name": "HelloRequest",
"extensions": null,
"enums": [],
"extends": [],
"options": {},
"messages": [],
"fields": [
{
"name": "greeting",
"type": "string",
"tag": 1,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
},
{
"name": "HelloResponse",
"extensions": null,
"enums": [],
"extends": [],
"messages": [],
"options": {},
"fields": [
{
"name": "reply",
"type": "string",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
}
]
}
],
"services": [
{
"name": "HelloService",
"methods": [
{
"name": "SayHello",
"input_type": "HelloRequest",
"output_type": "HelloResponse",
"client_streaming": false,
"server_streaming": false,
"options": {
"google.api.http": {
"get": "/v1/say-hello/echo/{greeting}",
"additional_bindings": [
{
"post": "/v2/say-hello",
"body": "greeting"
},
{
"get": "/v2/say-hello"
}
]
}
}
},
{
"name": "LotsOfReplies",
"input_type": "HelloRequest",
"output_type": "HelloResponse",
"client_streaming": false,
"server_streaming": true,
"options": {}
},
{
"name": "LotsOfGreetings",
"input_type": "HelloRequest",
"output_type": "HelloResponse",
"client_streaming": true,
"server_streaming": false,
"options": {
"google.api.http": {
"post": "/v1/lots-of-greetings",
"body": "*"
}
}
},
{
"name": "BidiHello",
"input_type": "HelloRequest",
"output_type": "HelloResponse",
"client_streaming": true,
"server_streaming": true,
"options": {}
}
],
"options": {}
}
],
"options": {}
}

View File

@@ -0,0 +1,30 @@
message HelloRequest {
optional string greeting = 1;
}
message HelloResponse {
required string reply = 1;
}
service HelloService {
rpc SayHello(HelloRequest) returns (HelloResponse) {
option (google.api.http) = {
get: "/v1/say-hello/echo/{greeting}"
additional_bindings {
post: "/v2/say-hello"
body: "greeting"
}
additional_bindings {
get: "/v2/say-hello"
}
};
}
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {
option (google.api.http) = {
post: "/v1/lots-of-greetings"
body: "*"
};
}
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}

View File

@@ -0,0 +1,35 @@
message EnumCarrying{
enum E{
A = 0;
B = 1;
}
}
message ValidPacked {
// varint wire types
repeated int32 f1 = 1 [packed = true];
repeated int64 f2 = 2 [packed = true];
repeated uint32 f3 = 3 [packed = true];
repeated uint64 f4 = 4 [packed = true];
repeated sint32 f5 = 5 [packed = true];
repeated sint64 f6 = 6 [packed = true];
repeated bool f7 = 7 [packed = true];
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
}
repeated Corpus f8 = 8 [packed = true];
repeated EnumCarrying.E f9 = 9 [packed = true];
// 64-bit wire types
repeated fixed64 f10 = 10 [packed = true];
repeated sfixed64 f11 = 11 [packed = true];
repeated double f12 = 12 [packed = true];
// 32-bit wire types
repeated fixed32 f13 = 13 [packed = true];
repeated sfixed32 f14 = 14 [packed = true];
repeated float f15 = 15 [packed = true];
}

View File

@@ -0,0 +1,90 @@
{
"syntax": 2,
"package": null,
"imports": [],
"enums": [],
"extends": [],
"messages": [
{
"name": "Point",
"enums": [],
"extends": [],
"messages": [],
"extensions": null,
"options": {},
"fields": [
{
"name": "x",
"type": "int32",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "y",
"type": "int32",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
},
{
"name": "Line",
"enums": [],
"extends": [],
"extensions": null,
"options": {},
"messages": [],
"fields": [
{
"name": "start",
"type": "Point",
"tag": 1,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "end",
"type": "Point",
"tag": 2,
"map": null,
"oneof": null,
"required": true,
"repeated": false,
"options": {}
},
{
"name": "label",
"type": "string",
"tag": 3,
"map": null,
"oneof": null,
"required": false,
"repeated": false,
"options": {}
}
]
}
],
"options":{}
}

View File

@@ -0,0 +1,13 @@
syntax = "proto2";
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}

157
node_modules/protocol-buffers-schema/test/index.js generated vendored Normal file
View File

@@ -0,0 +1,157 @@
var tape = require('tape')
var path = require('path')
var fs = require('fs')
var schema = require('../')
var fixture = function (name) {
return fs.readFileSync(path.join(__dirname, 'fixtures', name), 'utf-8')
}
tape('basic parse', function (t) {
t.same(schema.parse(fixture('basic.proto')), require('./fixtures/basic.json'))
t.end()
})
tape('basic parse + stringify', function (t) {
var syntax = 'syntax = "proto3";\n\n'
t.same(schema.stringify(schema.parse(fixture('basic.proto'))), syntax + fixture('basic.proto'))
t.end()
})
tape('complex parse', function (t) {
t.same(schema.parse(fixture('complex.proto')), require('./fixtures/complex.json'))
t.end()
})
tape('complex parse + stringify', function (t) {
var syntax = 'syntax = "proto3";\n\n'
t.same(schema.stringify(schema.parse(fixture('complex.proto'))), syntax + fixture('complex.proto'))
t.end()
})
tape('throws on invalid', function (t) {
t.plan(2)
try {
schema.parse('hello world')
} catch (err) {
t.ok(true, 'should fail')
}
try {
schema.parse('message Foo { lol }')
} catch (err) {
t.ok(true, 'should fail')
}
})
tape('comments parse', function (t) {
t.same(schema.parse(fixture('comments.proto')), require('./fixtures/comments.json'))
t.end()
})
tape('schema with imports', function (t) {
t.same(schema.parse(fixture('search.proto')), require('./fixtures/search.json'))
t.end()
})
tape('schema with imports loaded by path', function (t) {
t.same(schema.parse(fixture('search.proto')), require('./fixtures/search.json'))
t.end()
})
tape('schema with extends', function (t) {
t.same(schema.parse(fixture('extend.proto')), require('./fixtures/extend.json'))
t.end()
})
tape('comparing extended and not extended schema', function (t) {
var sch = schema.parse(fixture('extend.proto'))
t.same(sch.messages.MsgNormal, sch.messages.MsgExtend)
t.end()
})
tape('schema with oneof', function (t) {
t.same(schema.parse(fixture('oneof.proto')), require('./fixtures/oneof.json'))
t.end()
})
tape('schema with map', function (t) {
t.same(schema.parse(fixture('map.proto')), require('./fixtures/map.json'))
t.end()
})
tape('schema with syntax version', function (t) {
t.same(schema.parse(fixture('version.proto')), require('./fixtures/version.json'))
t.end()
})
tape('throws on misplaced syntax version', function (t) {
t.plan(1)
try {
schema.parse('message Foo { required int32 a = 1; }\n syntax = "proto3"')
} catch (err) {
t.ok(true, 'should fail')
}
})
tape('schema with reserved characters in options', function (t) {
t.same(schema.parse(fixture('options.proto')), require('./fixtures/options.json'))
t.end()
})
tape('service parse', function (t) {
t.same(schema.parse(fixture('service.proto')), require('./fixtures/service.json'))
t.end()
})
tape('service parse + stringify', function (t) {
var syntax = 'syntax = "proto3";\n\n'
t.same(schema.stringify(schema.parse(fixture('service.proto'))), syntax + fixture('service.proto'))
t.end()
})
tape('import parse + stringify', function (t) {
var syntax = 'syntax = "proto3";\n\n'
t.same(schema.stringify(schema.parse(fixture('search.proto'))), syntax + fixture('search.proto'))
t.end()
})
tape('enums with options', function (t) {
t.same(schema.parse(fixture('enum.proto')), require('./fixtures/enum.json'))
t.end()
})
tape('fail on no tags', function (t) {
t.throws(function () {
schema.parse(fixture('no-tags.proto'))
})
t.end()
})
tape('reserved', function (t) {
t.same(schema.parse(fixture('reserved.proto')), require('./fixtures/reserved.json'))
t.end()
})
tape('varint, 64-bit and 32-bit wire types can be packed', function (t) {
t.doesNotThrow(function () {
schema.parse(fixture('valid-packed.proto'))
}, 'should not throw')
t.end()
})
tape('non-primitive packed should throw', function (t) {
t.throws(function () {
schema.parse(fixture('pheromon-trajectories.proto'))
}, 'should throw')
t.end()
})
tape('custom options parse', function (t) {
t.same(schema.parse(fixture('option.proto')), require('./fixtures/option.json'))
t.end()
})
tape('escaped quotes in option value parse', function (t) {
t.same(schema.parse(fixture('escaped-quotes.proto')), require('./fixtures/escaped-quotes.json'))
t.end()
})

56
node_modules/protocol-buffers-schema/tokenize.js generated vendored Normal file
View File

@@ -0,0 +1,56 @@
module.exports = function (sch) {
var noComments = function (line) {
var i = line.indexOf('//')
return i > -1 ? line.slice(0, i) : line
}
var noMultilineComments = function () {
var inside = false
return function (token) {
if (token === '/*') {
inside = true
return false
}
if (token === '*/') {
inside = false
return false
}
return !inside
}
}
var trim = function (line) {
return line.trim()
}
var removeQuotedLines = function (list) {
return function (str) {
var s = '$' + list.length + '$'
list.push(str)
return s
}
}
var restoreQuotedLines = function (list) {
var re = /^\$(\d+)\$$/
return function (line) {
var m = line.match(re)
return m ? list[+m[1]] : line
}
}
var replacements = []
return sch
.replace(/"(\\"|[^"\n])*?"|'(\\'|[^'\n])*?'/gm, removeQuotedLines(replacements))
.replace(/([;,{}()=:[\]<>]|\/\*|\*\/)/g, ' $1 ')
.split(/\n/)
.map(trim)
.filter(Boolean)
.map(noComments)
.map(trim)
.filter(Boolean)
.join('\n')
.split(/\s+|\n+/gm)
.filter(noMultilineComments())
.map(restoreQuotedLines(replacements))
}