///|
/// Check names before rendering. Keep provider names intact on success.
fn check_generated_names(ctx : GoContext) -> Unit raise @codegen.CodegenError {
let declarations : Array[(String, String)] = [
("Peer", "generated peer"),
("Handlers", "generated handlers"),
("NewPeer", "generated peer constructor"),
("Contract", "generated contract"),
("decodeValue", "generated value decoder"),
("decodeObject", "generated object decoder"),
("pointer", "generated pointer helper"),
]
let error_shapes : Set[@smithy.ShapeId] = Set([])
for peer in ctx.description.peers {
if peer.accepts is Some(service) {
for method_ in service.methods {
for error in method_.errors {
error_shapes.add(error.shape)
}
}
}
}
for id in ctx.shapes {
if id.namespace() == "smithy.api" {
continue
}
let shape = ctx.shape(id)
let name = ctx.name(id)
match shape.body {
Simple(_)
| Structure(_)
| List(_)
| Map(..)
| Union(_)
| Enum(_)
| IntEnum(_) => declarations.push((name, id.to_string()))
_ => continue
}
match shape.body {
Union(ids) => {
declarations.push(("decode" + name, id.to_string()))
for member_ in ids {
declarations.push((name + ctx.field(member_), member_.to_string()))
}
}
Enum(ids) | IntEnum(ids) =>
for member_ in ids {
declarations.push((name + ctx.field(member_), member_.to_string()))
}
Structure(ids) =>
for member_ in ids {
let field = ctx.field(member_)
if field == "UnmarshalJSON" ||
(error_shapes.contains(id) && ["Error", "RPCError"].contains(field)) {
raise @codegen.InvalidSettings(
"I found a Go member name conflict for member `\{member_}` at `\{field}`.",
)
}
}
_ => ()
}
}
let methods : Array[(String, String)] = [
"Peer", "Serve", "Ready", "Close", "State", "HasCapability", "Call", "CallWithID",
"CallUnchecked", "Notify", "Register",
].map(name => (name, "runtime peer method"))
if ctx.selected.calls is Some(service) {
for method_ in service.methods {
let name = ctx.name(method_.operation)
let construct = method_.operation.to_string()
methods.push((name, construct))
if method_.kind == @rpc.RequestOrNotification {
methods.push(("Notify" + name, construct))
}
if method_.kind != @rpc.NotificationOnly {
declarations.push(("decode" + name + "Error", construct))
}
}
}
check_name_list(declarations, "declaration")
check_name_list(methods, "method")
}
///|
fn check_name_list(
names : Array[(String, String)],
kind : String,
) -> Unit raise @codegen.CodegenError {
names.sort_by((a, b) => {
let order = a.0.lexical_compare(b.0)
if order == 0 {
a.1.lexical_compare(b.1)
} else {
order
}
})
for index = 1; index < names.length(); index = index + 1 {
if names[index - 1].0 == names[index].0 {
raise @codegen.InvalidSettings(
"I found a Go \{kind} name conflict for construct `\{names[index].1}` at `\{names[index].0}` with construct `\{names[index - 1].1}`.",
)
}
}
}