Skip to content

Instantly share code, notes, and snippets.

@timostamm
Created October 27, 2022 13:41
Show Gist options
  • Save timostamm/9bafd4133e886978cf6647b4fa0b26c1 to your computer and use it in GitHub Desktop.
Save timostamm/9bafd4133e886978cf6647b4fa0b26c1 to your computer and use it in GitHub Desktop.
Using exports and imports in @bufbuild/protoplugin
import {localName, GeneratedFile, ImportSymbol, Schema} from "@bufbuild/protoplugin/ecmascript";
import type {DescMessage} from "@bufbuild/protobuf";
export function generateTs(schema: Schema) {
const map = new Map<DescMessage, ImportSymbol>();
function getFunctionName(f: GeneratedFile, message: DescMessage): ImportSymbol {
let s = map.get(message);
if (!s) {
s = f.export(`validate${localName(message)}`);
map.set(message, s);
}
return s;
}
function generateMessage(f: GeneratedFile, message: DescMessage) {
f.print("export function ", getFunctionName(f, message), "() {");
for (const field of message.fields) {
if (field.fieldKind === "message") {
f.print(" ", getFunctionName(f, field.message), "();");
}
}
f.print("}");
for (const nestedMessage of message.nestedMessages) {
generateMessage(f, nestedMessage);
}
}
for (const file of schema.files) {
const f = schema.generateFile(file.name + "_validate.ts");
for (const message of file.messages) {
generateMessage(f, message);
}
}
}
@timostamm
Copy link
Author

But quite frankly, this is pretty awkward 🙈
Your f.import(name, ... above seems much more straight forward!

function generateTs(schema: Schema) {
  function getFunctionName(f: GeneratedFile, message: DescMessage): ImportSymbol {
    const name = `validate${localName(message)}`;
    return f.import(name, `./${message.file.name}_validate.js`);
  }

  function generateMessage(f: GeneratedFile, message: DescMessage) {
    f.print("export function ", getFunctionName(f, message), "() {");
    for (const field of message.fields) {
      if (field.fieldKind === "message") {
        f.print("  ", getFunctionName(f, field.message), "();");
      }
    }
    f.print("}");
    for (const nestedMessage of message.nestedMessages) {
      generateMessage(f, nestedMessage);
    }
  }

  for (const file of schema.files) {
    const f = schema.generateFile(file.name + "_validate.ts");
    for (const message of file.messages) {
      generateMessage(f, message);
    }
  }
}

Thanks for shaking this out ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment